Commit 6b410e45 张士柳

1 个父辈 6cf73433
......@@ -80,7 +80,7 @@ int AZONNXWrapper::init(const std::string& model_path)
if (!model_path.empty()) {
try {
//加载并初始化网络
net_ = cv::dnn::readNet(model_path);
net_ = cv::dnn::readNetFromONNX(model_path);
net_.setPreferableBackend(cv::dnn::Backend::DNN_BACKEND_OPENCV);
net_.setPreferableTarget(cv::dnn::Target::DNN_TARGET_CPU);
}
......@@ -93,11 +93,11 @@ int AZONNXWrapper::init(const std::string& model_path)
return -1;
}
void AZONNXWrapper::setInputParams(float fConfThreshold, float fNmsThreshold, int top_k)
void AZONNXWrapper::setInputParams(float fConfThreshold, float fNmsThreshold, int targetSize)
{
this->fConfThreshold = fConfThreshold;
this->fNmsThreshold = fNmsThreshold;
this->top_k = top_k;
this->targetSize = targetSize;
}
float* AZONNXWrapper::forward(cv::Mat& img, cv::Scalar& mean, cv::Scalar& std)
......@@ -214,7 +214,7 @@ void AZONNXWrapper::forward(cv::Mat& img, cv::Mat& labels, cv::Mat& stats, cv::M
transpMask.copyTo(cc);
//非极大值抑制
std::vector<int> indices;
cv::dnn::NMSBoxes(boxes, confidences, fConfThreshold, fNmsThreshold, indices, 1.f, top_k);
cv::dnn::NMSBoxes(boxes, confidences, fConfThreshold, fNmsThreshold, indices, 1.f, 200);
//输出结果
labels = cv::Mat(Y, X, CV_32S, cv::Scalar(-1)), stats = cv::Mat(indices.size(), 5, CV_32FC1, cv::Scalar(0));
for (int i = 0; i < indices.size(); ++i)
......@@ -284,7 +284,7 @@ void AZONNXWrapper::forward(cv::Mat& img, cv::Mat& labels, cv::Mat& stats, cv::M
priorbox = NULL;
}
void AZONNXWrapper::forward(cv::Mat& img) {
std::vector<cv::Rect> AZONNXWrapper::forward(cv::Mat& img) {
#pragma warning( disable : 26451 )
CV_Assert(!img.empty());
//图像预处理,仅支持单通道
......@@ -296,118 +296,77 @@ void AZONNXWrapper::forward(cv::Mat& img) {
else {
img.copyTo(input);
}
const int targetSize = 640;
cv::resize(input, input, cv::Size(targetSize, targetSize));
cv::Mat blob;
cv::dnn::blobFromImage(input, blob, 1.0 / 255., cv::Size(targetSize, targetSize), cv::Scalar(114, 114, 114), true);
net_.setInput(blob);
//
const float netStride[4] = { 8, 16.0,32,64 };
//const float anchors[3][6] = { {12, 16, 19, 36, 40, 28},{36, 75, 76, 55, 72, 146},{142, 110, 192, 243, 459, 401} }; //yolov7-P5 anchors
const float anchors[3][6] = { {10, 13, 16, 30, 33, 23},{30, 61, 62, 45, 59, 119},{116, 90, 156, 198, 373, 326} }; //yolov7-tiny anchors
auto x = net_.getUnconnectedOutLayersNames();
//推理
std::vector<cv::Mat> preds;
net_.forward(preds, net_.getUnconnectedOutLayersNames());
//图像预处理
const int maxLen = MAX(input.cols, input.rows);
//获取结果
std::vector<int> classIds;
std::vector<float> confidences;
std::vector<cv::Rect> boxes;
int top0 = 0, down0 = 0, left0 = 0, right0 = 0;
top0 = (maxLen - input.rows) / 2;
down0 = (maxLen - input.rows) / 2;
left0 = (maxLen - input.cols) / 2;
right0 = (maxLen - input.cols) / 2;
cv::copyMakeBorder(input, input, top0, down0, left0, right0, cv::BORDER_CONSTANT, cv::Scalar(114, 114, 114));
float ratioY = (float)img.rows / targetSize;
float ratioX = (float)img.cols / targetSize;
cv::Mat blob;
cv::dnn::blobFromImage(input, blob, 1 / 255.0, cv::Size(targetSize, targetSize), cv::Scalar(), true, false);
const int nc = 1;
const float netStride[4] = { 8, 16.0,32,64 };
//for (int stride = 0; stride < preds.size(); stride++)
//{
// float* pdata = (float*)preds[stride].data;
// int T = (int)(targetSize / netStride[stride]);
// for (int anchor = 0; anchor < 3; anchor++)
// {
// const float anchor_w = netAnchors[stride][anchor * 2];
// const float anchor_h = netAnchors[stride][anchor * 2 + 1];
// for (int h = 0; h < T; h++)
// {
// for (int w = 0; w < T; w++)
// {
// float box_score = sigmoid_x(pdata[4]); ;//获取每一行的box框中含有某个物体的概率
// if (box_score >= fConfThreshold) {
// cv::Mat scores(1, nc, CV_32FC1, pdata + 5);
// cv::Point classIdPoint;
// double max_class_socre;
// minMaxLoc(scores, 0, &max_class_socre, 0, &classIdPoint);
// max_class_socre = sigmoid_x(max_class_socre);
// if (max_class_socre >= fConfThreshold) {
// float x = (sigmoid_x(pdata[0]) * 2.f - 0.5f + w) * netStride[stride]; //x
// float y = (sigmoid_x(pdata[1]) * 2.f - 0.5f + h) * netStride[stride]; //y
// float w = powf(sigmoid_x(pdata[2]) * 2.f, 2.f) * anchor_w; //w
// float h = powf(sigmoid_x(pdata[3]) * 2.f, 2.f) * anchor_h; //h
// int left = (int)(x - 0.5 * w) * ratioX + 0.5;
// int top = (int)(y - 0.5 * h) * ratioY + 0.5;
// classIds.push_back(classIdPoint.x);
// confidences.push_back(max_class_socre * box_score);
// boxes.push_back(cv::Rect(left, top, int(w * ratioX), int(h * ratioY)));
// }
// }
// pdata += (nc + 1);
// }
// }
// }
//}
auto layerNames = net_.getUnconnectedOutLayersNames();
//float ratioY = (float)input.rows / targetSize;
//float ratioX = (float)input.cols / targetSize;
for (int stride = 0; stride < 3; stride++)
{
float* pdata = (float*)preds[stride].data;
int gridX = (int)(targetSize / netStride[stride]);
int gridY = (int)(targetSize / netStride[stride]);
net_.setInput(blob);
std::vector<cv::Mat> netOutputImg;
net_.forward(netOutputImg, net_.getUnconnectedOutLayersNames());
std::vector<std::string> className0 = { "target" };
std::vector<int> classIds;//结果id数组
std::vector<float> confidences;//结果每个id对应置信度数组
std::vector<cv::Rect> boxes;//每个id矩形框
float ratio_h = (float)input.rows / targetSize;
float ratio_w = (float)input.cols / targetSize;
int netstep = className0.size() + 5; //输出的网络宽度是类别数+5
for (int stride = 0; stride < 3; stride++) {
float* pdata = (float*)netOutputImg[stride].data;
int grid_x = (int)(targetSize / netStride[stride]);
int grid_y = (int)(targetSize / netStride[stride]);
for (int anchor = 0; anchor < 3; anchor++) {
const float anchor_w = netAnchors[stride][anchor * 2];
const float anchor_h = netAnchors[stride][anchor * 2 + 1];
for (int i = 0; i < gridY; i++) {
for (int j = 0; j < gridX; j++) {
const float anchor_w = anchors[stride][anchor * 2];
const float anchor_h = anchors[stride][anchor * 2 + 1];
for (int i = 0; i < grid_y; i++) {
for (int j = 0; j < grid_x; j++) {
float box_score = sigmoid_x(pdata[4]); ;//获取每一行的box框中含有某个物体的概率
if (box_score >= fConfThreshold) {
cv::Mat scores(1, nc, CV_32FC1, pdata + 5);
cv::Mat scores(1, className0.size(), CV_32FC1, pdata + 5);
cv::Point classIdPoint;
double max_class_socre;
minMaxLoc(scores, 0, &max_class_socre, 0, &classIdPoint);
max_class_socre = sigmoid_x(max_class_socre);
max_class_socre = sigmoid_x(max_class_socre) / 0.5;
if (max_class_socre >= fConfThreshold) {
float x = (sigmoid_x(pdata[0]) * 2.f - 0.5f + j) * netStride[stride]; //x
float y = (sigmoid_x(pdata[1]) * 2.f - 0.5f + i) * netStride[stride]; //y
float w = powf(sigmoid_x(pdata[2]) * 2.f, 2.f) * anchor_w; //w
float h = powf(sigmoid_x(pdata[3]) * 2.f, 2.f) * anchor_h; //h
int left = (int)(x - 0.5 * w) * ratioX + 0.5;
int top = (int)(y - 0.5 * h) * ratioY + 0.5;
float h = powf(sigmoid_x(pdata[3]) * 2.f, 2.f) * anchor_h; //h
int left = (int)(x - 0.5 * w) * ratio_w + 0.5 - left0;
int top = (int)(y - 0.5 * h) * ratio_h + 0.5 - top0;
classIds.push_back(classIdPoint.x);
confidences.push_back(max_class_socre * box_score);
boxes.push_back(cv::Rect(left, top, int(w * ratioX), int(h * ratioY)));
confidences.push_back(/*max_class_socre * */box_score);
boxes.push_back(cv::Rect(left, top, int(w * ratio_w), int(h * ratio_h)));
}
}
pdata += 6;
pdata += netstep;
}
}
}
}
//执行非最大抑制以消除具有较低置信度的冗余重叠框(NMS)
std::vector<int> indices;
//非最大抑制
std::vector<int> indices; std::vector<cv::Rect> bboxes;
cv::dnn::NMSBoxes(boxes, confidences, fConfThreshold, fNmsThreshold, indices);
for (int i = 0; i < indices.size(); ++i)
{
for (int i = 0; i < indices.size(); i++) {
int idx = indices[i];
cv::Rect box = boxes[idx];
int xmax = box.x + box.width;
int ymax = box.y + box.height;
cv::rectangle(img, cv::Point(box.x, box.y), cv::Point(xmax, ymax), cv::Scalar(0, 0, 255, 255), 1);
bboxes.push_back(boxes[idx]);
}
return;
return bboxes;
}
AZONNXWrapper::AZONNXWrapper() {
......@@ -416,4 +375,4 @@ AZONNXWrapper::AZONNXWrapper() {
AZONNXWrapper::~AZONNXWrapper() {
delete[] predictions;
predictions = NULL;
}
\ No newline at end of file
}
......@@ -16,11 +16,11 @@ public:
int init(const std::string& model_path);
float* forward(cv::Mat& img, cv::Scalar& mean, cv::Scalar& std); //ResNet18提取特征[1,512]
void forward(cv::Mat& img, cv::Mat& labels, cv::Mat& stats, cv::Mat& drawResult, cv::Scalar& mean, cv::Scalar& std); //Yolact实例分割
void forward(cv::Mat& img); //YOLOV7
std::vector<cv::Rect> forward(cv::Mat& img); //YOLOv7
void setInputParams(float, float, int);
private:
int targetSize = 550;
float fConfThreshold = 0.5; float fNmsThreshold = 0.5; int top_k = 200;
int targetSize = 640;
float fConfThreshold = 0.5; float fNmsThreshold = 0.5;
float* predictions = new float[512];
cv::dnn::Net net_;
......@@ -131,7 +131,6 @@ protected:
const float var[4] = { 0.1f, 0.1f, 0.2f, 0.2f };
const int mask_h = 138;
const int mask_w = 138;
const float netAnchors[3][6] = { {12, 16, 19, 36, 40, 28},{36, 75, 76, 55, 72, 146},{142, 110, 192, 243, 459, 401} };//YOLOV7-P5
float* priorbox = NULL;
};
......
......@@ -13,7 +13,6 @@ static double calcDist2D(const EyemOcsDXY2D taPointP, double dA, double dB, doub
static void weightL1(float* d, int count, float* w, float _c)
{
int i;
for (i = 0; i < count; i++)
{
double t = fabs((double)d[i]);
......@@ -24,7 +23,6 @@ static void weightL1(float* d, int count, float* w, float _c)
static void weightL12(float* d, int count, float* w, float _c)
{
int i;
for (i = 0; i < count; i++)
{
w[i] = 1.0f / (float)std::sqrt(1 + (double)(d[i] * d[i] * 0.5));
......@@ -833,12 +831,4 @@ int eyemRobustFitEllipse(int iPtnNum, EyemOcsDXY* taPoint, int iCalcMode, double
return FUNC_OK;
}
int eyemRobustFitRectangle(int iPtnNum, EyemOcsDXY* taPoint, int iCalcMode, double dRobustCoef, EyemRotateRect& tpRect)
{
//先计算最小外包,然后计算各点到矩形的最小平方差和
//cv::minAreaRect();
return FUNC_OK;
}
......@@ -11,7 +11,7 @@
#ifdef VQISDA
#define FILEVERSION "2.4.9.8 (Only Qisda)"
#else
#define FILEVERSION "2.4.9.10"
#define FILEVERSION "2.4.9.11"
#endif
#endif
......@@ -551,6 +551,7 @@ extern "C" {
EXPORTS int eyemClp2dCircleThreePoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, EyemOcsDXYR& tpCircle);
EXPORTS int eyemClp2dIntersectionLineAndCircle(EyemOcsDABC tpLine, EyemOcsDXYR tpCircle, EyemOcsDXY& tpPoint1, EyemOcsDXY& tpPoint2);
EXPORTS int eyemClp2dTangentPointToCircle(EyemOcsDXY tpPoint, EyemOcsDXYR tpCircle, EyemOcsDABC& tpTangent1, EyemOcsDXY& tpContact1, EyemOcsDABC& tpTangent2, EyemOcsDXY& tpContact2);
EXPORTS void eyemClp2dIntersectionOfLineRectangle(EyemOcsDABC tpLine, EyemOcsDXY p0, EyemOcsDXY p1, EyemOcsDXY p2, EyemOcsDXY& tpPoint0, EyemOcsDXY& tpPoint1);
#ifdef __cplusplus
}
......@@ -926,18 +927,18 @@ typedef struct {
double dAngle; // 角度
int iCenterX; // y坐标
int iCenterY; // y坐标
char* lpszType; // 码类型
char* lpszText; // 码内容
char* lpszType; // 码类型
char* lpszText; // 码内容
} EyemBarCode;
typedef struct {
void* vpImage; // 地址
void* vpImage; // 地址
int iXs; // 图像X坐标
int iYs; // 图像Y坐标
int iWidth; // 图像内存X方向大小
int iHeight; // 图像内存Y方向大小
double dMatchDeg; // 匹配度
char* lpszName; // 名称
char* lpszName; // 名称
} EyemModelID;
#ifdef __cplusplus
......@@ -978,6 +979,7 @@ extern "C" {
EXPORTS int eyemSIFTBasedMatch(EyemImage tpImage, EyemImage tpTargetImg, EyemImage tpMask, double dMinScore, EyemImage* tpDstImg);
EXPORTS int eyemAchvMaskImage(EyemImage tpImage, EyemImage* tpDstImg, EyemImage* tpPrevImg);
EXPORTS int eyemSplitMask(EyemImage tpImage, EyemImage tpMask, const char* ccToPath, const char* ccClassName);
EXPORTS int eyemCalcReelTHK(EyemImage tpImage, EyemImage tpMask, EyemOcsIXY*, double& dThickness);
#ifdef __cplusplus
......
此文件类型无法预览
......@@ -4,22 +4,32 @@ class NNDetector::Impl {
public:
Impl() {}
~Impl() {}
//目标检测
std::vector<cv::Rect> detect(const cv::Mat& img);
//目标检测器
#ifdef _V455
std::shared_ptr<AZONNXWrapper> detector_;
#else
std::shared_ptr<YoloWrapper> detector_;
#endif
//目标检测参数
float _fConfidence = 0.01f, _fNMSThreshold = 0.05f;
float _fConfidence = 0.1f, _fNMSThreshold = 0.15f;
};
NNDetector::NNDetector(const std::string & detector_config_path,
const std::string & detector_model_path, const cv::Size& input_size)
NNDetector::NNDetector(const std::string& detector_config_path,
const std::string& detector_model_path, const cv::Size& input_size)
{
p = cv::makePtr<NNDetector::Impl>();
if (!detector_config_path.empty() && !detector_model_path.empty()) {
p->detector_ = std::make_shared<YoloWrapper>();
p->detector_->init(detector_config_path, detector_model_path, input_size);
if (!detector_model_path.empty()) {
#ifdef _V455
p->detector_ = std::make_shared<AZONNXWrapper>();
p->detector_->init(detector_model_path);
#else
if (!detector_config_path.empty()) {
p->detector_ = std::make_shared<YoloWrapper>();
p->detector_->init(detector_config_path, detector_model_path, input_size);
}
#endif
}
else {
p->detector_ = NULL;
......@@ -49,11 +59,18 @@ std::vector<cv::Rect> NNDetector::detect(cv::InputArray img)
}
std::vector<cv::Rect> NNDetector::Impl::detect(const cv::Mat& img) {
#ifdef _V455
detector_->setInputParams(_fConfidence, _fNMSThreshold, 640);
cv::Mat input;
img.copyTo(input);
return detector_->forward(input);
#else
detector_->setPreferableParams(_fConfidence, _fNMSThreshold);
return detector_->forward(img);
#endif
}
int eyemInitNNDetector(const char *detectorConfigPath, const char *detectorModelPath, int iNetSizew, int iNetSizeh)
int eyemInitNNDetector(const char* detectorConfigPath, const char* detectorModelPath, int iNetSizew, int iNetSizeh)
{
try {
pNNDetector = cv::makePtr<NNDetector>(detectorConfigPath, detectorModelPath, cv::Size(iNetSizew, iNetSizeh));
......@@ -71,7 +88,7 @@ int eyemNNDetectorParams(float fConfidence, float fNMSThreshold)
return FUNC_OK;
}
int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, EyemImage *tpDstImg)
int eyemNNDetector(EyemImage tpImage, int* ipNum, BboxContainer& container, EyemImage* tpDstImg)
{
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (src.empty()) {
......@@ -109,9 +126,9 @@ int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container, Eyem
//<输出计数结果标记图像
tpDstImg->iWidth = input.cols; tpDstImg->iHeight = input.rows; tpDstImg->iDepth = input.depth(); tpDstImg->iChannels = input.channels();
//内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
int _Size = tpDstImg->iWidth * tpDstImg->iHeight * tpDstImg->iChannels * sizeof(uint8_t);
//分配初始化内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size);
tpDstImg->vpImage = (uint8_t*)malloc(_Size);
if (NULL == tpDstImg->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImg->vpImage, 0, _Size);
......
......@@ -7,6 +7,10 @@
#include "eyemLib.h"
#include "yoloWrapper.h"
#ifdef _V455
#include "azONNXWrapper.h"
#endif
class NNDetector {
public:
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!