复现yolov5CPP经验贴

源码:
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);
}

欢迎交流
在这里插入图片描述
加好友交流,还请备注姓名,专业,否则可能无法验证通过,谢谢配合,

猜你喜欢

转载自blog.csdn.net/wxy2020915/article/details/128617159