yolov5-dnn-cpp-python
https://github.com/hpc203/yolov5-dnn-cpp-python
转onnx:
用opencv的dnn模块做yolov5目标检测的程序,包含两个步骤:(1).把pytorch的训练模型.pth文件转换到.onnx文件。(2).opencv的dnn模块读取.onnx文件做前向计算。
SiLU其实就是swish激活函数,而在onnx模型里是不直接支持swish算子的,因此在转换生成onnx文件时,SiLU激活函数不能直接使用nn.Module里提供的接口,而需要自定义实现它。
修改Focus类,替换切片操作。
把Detect类里面的1x1卷积定义在紧邻着Detect类之前的外面,然后去掉Detect类,组成新的model,作为torch.onnx.export的输入。
torch.onnx.export(model, inputs, output_onnx, verbose=False, opset_version=12, input_names=['images'], output_names=['out0', 'out1', 'out2'])
最后生成的onnx文件,opencv的dnn模块就能成功读取了,接下来对照Detect类里的forward函数,用python或者C++编写计算预测框的中心坐标和高宽的功能。
在转换生成onnx文件,你需要执行两个步骤,
第一步把原始训练模型.pt文件里的参数保存到新的.pth文件里,
第二步编写yolov5.py文件,把yolov5的网络结构定义在.py文件里,此时需要注意网络结构里不能包含切片对象赋值操作,F.interpolate里的size参数需要加int强制转换。
在执行完这两步之后才能生成一个opencv能成功读取并且做前向推理的onnx文件。
不过,最近我发现在yolov5-pytorch程序里,其实可以直接把原始训练模型.pt文件转换生成onnx文件的,而且我在一个yolov5检测人脸+关键点的程序里实验成功了。
https://blog.csdn.net/nihate/article/details/112731327
作者用的模型
https://github.com/hpc203/yolov5-dnn-cpp-python/issues/21
https://github.com/ultralytics/yolov5/releases/tag/v4.0
问题:
warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
https://blog.csdn.net/lcb_coconut/article/details/76136725
ModuleNotFoundError: No module named ‘models‘解决torch.load问题【天坑】
https://blog.csdn.net/weixin_42815846/article/details/115289861
抽取模型参数
转onnx成功,会打印如下信息
==============================================================================================================
yolov5-opencv-dnn-cpp
https://github.com/UNeedCryDear/yolov5-opencv-dnn-cpp (保存图片没有框)
opencv YOLO DNNs
https://docs.opencv.org/4.x/da/d9d/tutorial_dnn_yolo.html
cv::dnn::DetectionModel
void cv::dnn::DetectionModel::detect(
InputArray frame, // 输入图像
std::vector< int > & classIds, // 输出类别index
std::vector< float > & confidences, // 得分
std::vector< Rect > & boxes, // 目标框
float confThreshold = 0.5f, // 阈值
float nmsThreshold = 0.0f // NMS
)
https://cloud.tencent.com/developer/article/1536443
C++ 动态batch onnx推理
多个batch
//将image1和image2合并到images
vector<Mat> images;
images.push_back(image1);
images.push_back(image2);
vector<String> labels = readClassNames();
Mat inputBlob = blobFromImages(images, 1.0, Size(w, h), Scalar(0, 0, 0), false, true);
// 执行图像分类
net.setInput(inputBlob);
cv::Mat prob = net.forward(); // 推理出结果
cout << prob.cols<< endl;文章来源:https://www.toymoban.com/news/detail-520496.html
for (int n = 0; n < prob.rows; n++) {
Point classNumber;
double classProb;
Mat probMat = prob(Rect(0, n, 1000, 1)).clone();
Mat result = probMat.reshape(1, 1);
minMaxLoc(result, NULL, &classProb, NULL, &classNumber);
int classidx = classNumber.x;
printf("\n current image classification : %s, possible : %.2f\n", labels.at(classidx).c_str(), classProb);
}
https://blog.csdn.net/qq_44747572/article/details/121467657文章来源地址https://www.toymoban.com/news/detail-520496.html
到了这里,关于C++调用yolov5 onnx模型的初步探索的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!