源码:
https://github.com/Hexmagic/ONNX-yolov5/blob/master/src/test.cpp
该源码亲测可行,但是还是有一些问题
此处改成False
此处改成自己转换好的onnx模型路径
用神经网络工具:
https://github.com/lutzroeder/netron
用该工具可查看输入输出非常重要,不然后面参数设置没法设置,运行就会报错,有四个参数必须一致
输入的图像网络大小必须和转出模型输入网络大小一致都是640,640,不然报错
其次查看输出
必须一致
然后配置相应的opencv环境既可以,注意版本4.54以上的就有dnn推理模块,以下可能没有该模块,就容易报错
最后,源码还有一个问题,就是容易越界报错。
这段代码我改成如下:
上述即是我所遇到的问题。
我的自己修改后可执行代码:
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace cv;
using namespace std;
Mat letterbox(Mat &img, Size new_shape, Scalar color, bool _auto, bool scaleFill, bool scaleup, int stride)
{
float width = img.cols;
float height = img.rows;
float r = min(new_shape.width / width, new_shape.height / height);
if (!scaleup)
r = min(r, 1.0f);
int new_unpadW = int(round(width * r));
int new_unpadH = int(round(height * r));
int dw = new_shape.width - new_unpadW;
int dh = new_shape.height - new_unpadH;
if (_auto)
{
dw %= stride;
dh %= stride;
}
dw /= 2, dh /= 2;
Mat dst;
resize(img, dst, Size(new_unpadW, new_unpadH), 0, 0, INTER_LINEAR);
int top = int(round(dh - 0.1));
int bottom = int(round(dh + 0.1));
int left = int(round(dw - 0.1));
int right = int(round(dw + 0.1));
copyMakeBorder(dst, dst, top, bottom, left, right, BORDER_CONSTANT, color);
return dst;
}
int main(int argc, char *argv[])
{
string model_path = "muti_single_peson_15000best320.onnx";
dnn::Net model = dnn::readNetFromONNX(model_path);
Mat img0 = imread("1.png");
Mat img = letterbox(img0, Size(640, 640), Scalar(114, 114, 114), false, false, true, 32);
Mat blob;
dnn::blobFromImage(img, blob, 1 / 255.0f, Size(img.cols, img.rows), Scalar(0, 0, 0), true, false);
model.setPreferableBackend(dnn::DNN_BACKEND_OPENCV);
model.setPreferableTarget(dnn::DNN_TARGET_CPU);
model.setInput(blob);
vector<string> outLayerNames = model.getUnconnectedOutLayersNames();
vector<Mat> result;
model.forward(result, outLayerNames);
Mat out = Mat(result[0].size[1], result[0].size[2], CV_32F, result[0].ptr<float>());
vector<Rect> boxes;
vector<int> indices;
vector<float> scores;
for (int r = 0; r < out.size[0]; r++)
{
float cx = out.at<float>(r, 0);
float cy = out.at<float>(r, 1);
float w = out.at<float>(r, 2);
float h = out.at<float>(r, 3);
float sc = out.at<float>(r, 4);
Mat confs = out.row(r).colRange(5,85);
confs *= sc;
double minV = 0, maxV = 0;
double *minI = &minV;
double *maxI = &maxV;
minMaxIdx(confs, minI, maxI);
scores.push_back(maxV);
boxes.push_back(Rect(cx - w / 2, cy - h / 2, w, h));
indices.push_back(r);
}
dnn::NMSBoxes(boxes, scores, 0.25f, 0.45f, indices);
int index = 0;
for (auto &ind : indices)
{
cout << indices[index] << ":" << scores[ind] << endl;
Rect rect = boxes[indices[index++]];
cv::rectangle(img, rect, Scalar(0, 255, 0), 1, LINE_AA);
}
cv::imshow("output", img);
cv::waitKey(10000);
}
欢迎交流
加好友交流,还请备注姓名,专业,否则可能无法验证通过,谢谢配合,