深圳专业做网站哪家好百度平台营销宝典
- 作者: 五速梦信息网
- 时间: 2026年04月20日 09:19
当前位置: 首页 > news >正文
深圳专业做网站哪家好,百度平台营销宝典,开鲁seo网站,律师怎么做网站yolov5-7.0模型DNN加载函数及参数详解#xff08;重要#xff09; 引言yolov5#xff08;v7.0#xff09;1#xff0c;yolov5.h(加载对应模型里面的相关参数要更改)2#xff0c;main主程序#xff08;1#xff09;加载网络#xff08;2#xff09;检测推理#xff0… yolov5-7.0模型DNN加载函数及参数详解重要 引言yolov5v7.01yolov5.h(加载对应模型里面的相关参数要更改)2main主程序1加载网络2检测推理forward2.1制作黑背景正方形用于blobFromImage的无损缩放2.2blobFromImage改变图像格式为网络出入格式2.3输入setInput图像并forward推理2.4结果解析2.4.0方法0直接Mat读取解析主要用于理解输出结构2.4.1方法1指针法Mat.data解析快但不易理解 2.5绘制结果 引言 使用opencv的dnn模块对应yolov5v7.0的导出的onnx模型进行推理解析明确各个参数的对应含义及结果。理论上有了onnx模型有了该网络模型的输入输出各个参数含义就可以使用任意的可以读取onnx模型的部署框架进行部署推理。
yolov5v7.0
Yolov5v7.0 部署使用opencv4.5.5opencv4.5.4以上可以读取网络dnn模块部署
已经导出的cpu、opset12、640大小图像、默认静态
如上输入输出层在后面的DNN模块推理会用到
1yolov5.h(加载对应模型里面的相关参数要更改)
需要修改的相关参数如下要根据自己的模型来进行
#include fstream
#include sstream
#include iostream
#include opencv2/dnn.hpp
#include opencv2/imgproc.hpp
#include opencv2/highgui.hpp
using namespace cv;
using namespace dnn;
using namespace std;class YOLO
{
public:struct Detection{int class_id;float confidence;Rect box;};
public:YOLO();~YOLO();bool loadNet(string model_path, bool is_cuda);Mat formatYolov5(const Mat source);void detect(Mat image, vectorDetection output);void drawRect(Mat image, vectorDetection output);
private:Net m_net;//修改为训练时自己模型Img大小float inputWidth 640;float inputHeight 640;//修改 dimensions 类别数 5const int dimensions 6;//修改 通过Netron可查看图片大小320rows为6300图片大小640rows为25200const int rows 25200;float scoreThreshold 0.2;float nmsThreshold 0.4;float confThreshold 0.4;
public://修改为自己的类别数const vectorstring m_classNames { qrcode };/const std::vectorstd::string m_classNames { person, bicycle, car, motorcycle, airplane, bus, train, truck, boat, traffic light,fire hydrant, stop sign, parking meter, bench, bird, cat, dog, horse, sheep, cow,elephant, bear, zebra, giraffe, backpack, umbrella, handbag, tie, suitcase, frisbee,skis, snowboard, sports ball, kite, baseball bat, baseball glove, skateboard, surfboard,tennis racket, bottle, wine glass, cup, fork, knife, spoon, bowl, banana, apple,sandwich, orange, broccoli, carrot, hot dog, pizza, donut, cake, chair, couch,potted plant, bed, dining table, toilet, tv, laptop, mouse, remote, keyboard, cell phone,microwave, oven, toaster, sink, refrigerator, book, clock, vase, scissors, teddy bear,hair drier, toothbrush };/const vectorScalar colors { Scalar(255, 255, 0), Scalar(0, 255, 0), Scalar(0, 255, 255), Scalar(255, 0, 0) };
};2main主程序
int main(int argc, char** argv)
{Mat frame imread(2.jpeg);YOLO yolov5;//加载模型yolov5.loadNet(qrcode.onnx, false);std::vectorYOLO::Detection output;//进行检测//检测时间DWORD time_start, time_end;/* 获取开始时间 */time_start GetTickCount(); //从操作系统启动经过的毫秒数yolov5.detect(frame, output);time_end GetTickCount();int time (time_end - time_start);cout Time (time_end - time_start) ms\n ;//将所耗时间显示到图片上putText(frame, format(time:%dms, time), Point(20, 50), FONT_HERSHEY_SIMPLEX, 1.2, Scalar(255, 0,0), 2);//绘制结果yolov5.drawRect(frame, output);imshow(output, frame);waitKey(0);return 0;
}1加载网络
加载已经导出的onnx网络打印各个层级参数此时网络读取成功opencv要在4.5.4以上
bool YOLO::loadNet(string model_path, bool is_cuda)
{try {m_net readNet(model_path);//获取各层信息vectorstring layer_names m_net.getLayerNames(); //此时我们就可以获取所有层的名称了有了这些可以将其ID取出for (int i 0; i layer_names.size(); i) {int id m_net.getLayerId(layer_names[i]); //通过name获取其idauto layer m_net.getLayer(id); //通过id获取layerprintf(layer id:%d,type:%s,name:%s\n, id, layer-type.c_str(), layer-name.c_str()); //将每一层的id类型姓名打印出来可以明白此网络有哪些结构信息了}}catch (const std::exception) {cout load faild endl;return false;}if (is_cuda){cout Attempty to use CUDA\n;m_net.setPreferableBackend(DNN_BACKEND_CUDA);m_net.setPreferableTarget(DNN_TARGET_CUDA_FP16);}else{cout Running on CPU\n;m_net.setPreferableBackend(DNN_BACKEND_OPENCV);m_net.setPreferableTarget(DNN_TARGET_CPU);}return true;
}2检测推理forward
推理前要对图像进行预处理使其变为网络的输入格式
2.1制作黑背景正方形用于blobFromImage的无损缩放
也可以不制作黑背景但后面blobFromImage缩放计算可能结果有损失
//制作黑背景正方形用于blobFromImage的无损缩放
//对于长宽比过大的图片由于opencv的blobFromImage()函数在缩放的时候不是无损缩放
//会导致图像变形严重导致结果错误或者漏检。虽然blobFromImage里面有个参数可以保持比例缩放
//但是只会保留中间的部分两边信息全部丢掉所以如果你的目标全部在中间就可以无所谓
//如果不是那么需要简单的自己做个无损缩放制作一张全黑的3通道正方形图片边长为原图的长边
//最后将原图放在00的位置上面这样就可以直接输入blobFromImage里面就可以实现无损缩放了
//而且不用对检测结果进行二次修正位置了。
//https ://blog.csdn.net/qq_34124780/article/details/116464727
Mat YOLO::formatYolov5(const Mat source)
{int col source.cols;int row source.rows;int _max MAX(col, row);Mat result Mat::zeros(_max, _max, CV_8UC3);source.copyTo(result(Rect(0, 0, col, row)));return result;
}2.2blobFromImage改变图像格式为网络出入格式 Mat blob;auto input_image formatYolov5(image);blobFromImage(input_image, blob, 1. / 255., Size(inputWidth, inputHeight), Scalar(), true, false);//1. / 255.数据归一化图像大小变为输入格式640*640true进行通道交换false不进行切片此时经过blobFromImage的图像就变成4维了在imagewatch中不显示
2.3输入setInput图像并forward推理
m_net.setInput(blob);
vectorMat outputs;
m_net.forward(outputs, m_net.getUnconnectedOutLayersNames());Forward函数有很多可以得到如下有的是将所有的输出结果得到有时输出层有多个有的是将对应层的输出结果得到这里直接得到所有最终输出结果就行了
实际这里推理只有1个输出结果 cout outputs.size(): outputs.size() endl;2.4结果解析
实际此时推理输出为[1252006]共三维的图像使用指针的方法的话二维还是三维都会展开成一维指针进行读取
输出结果如下dims3维度
将其转换成Mat可以显示的方式用于查看对应的效果
效果如下
2.4.0方法0直接Mat读取解析主要用于理解输出结构 与指针相比通过mat数组获取对应的第4列的数据是对应的起来的如下应该使用32F数据格式即可要将其结果转为25200*6格式的数据保存到mat中
上图最右侧的第6列的数据是类的分数虽然显示1但实际上分值是浮点数接近1的
三维的
//使用Mat进行相关数据的保存解析这里主要通过mat用于理解对应的输出结构
void YOLO::detect2(Mat image, vectorDetection output) {Mat blob;auto input_image formatYolov5(image);blobFromImage(input_image, blob, 1. / 255., Size(inputWidth, inputHeight), Scalar(), true, false);//1. / 255.数据归一化图像大小变为输入格式640*640true进行通道交换false不进行切片m_net.setInput(blob);vectorMat outputs;m_net.forward(outputs, m_net.getUnconnectedOutLayersNames());//结果解析//方法0、使用Mat进行解析//***********输出测试//几个输出结果cout outputs.size(): outputs.size() endl;/Mat detect_res m_net.forward(output0);cout detect_res.channels(): detect_res.size() endl;cout outputs[0].channels(): outputs[0].size() endl;///对其结果使用下方的重新复制一个MAT这样的才能在imagewatch中看到否则无法显示Mat d1 outputs[0].clone();//重新定义一个Mat对象接收将其转换成输出结构rows 25200 dimensions6Mat detectionMat2(rows, dimensions, CV_32F, d1.ptrfloat()); //此处是初始化一个行为size[2]深度为浮点型数据从detection中获取 //使用imagewatch可以看到6*25200的数组单通道32F深度cout detect_res.rows: detectionMat2.rows endl;//先得到原始用于blobFromImage归一化的input_image图像与/640的比例后面用于目标框的结果返回float x_factor1 float(input_image.cols) / inputWidth; //用于blobFromImage归一化的input_image图像/640得到对应的比例float y_factor1 float(input_image.rows) / inputHeight; //用于blobFromImage归一化的input_image图像/640vectorint class_ids1;vectorfloat confidences1;vectorRect boxes1;//25200行的数据对应的onnx的输出参数for (int i 0; i detectionMat2.rows; i) {float confidence1 detectionMat2.atfloat(i, 4); //置信度方框box的得分分值//cout confidence1 confidence1 endl;if (confidence1 confThreshold) //求置信度某个值{//cout confidence1 confidence1 endl;//求类别得分将第一个类别后面的所有的类别作为一个mat一行//制作一个vector对象//循环从类别后面截取各个类的分值,并保存vectorfloat classes_scores1;for (int j 5; j detectionMat2.cols; j) {classes_scores1.push_back(detectionMat2.atfloat(i, j));}//求classes_scores1的最大值及对应的索引auto max_class_score max_element(classes_scores1.begin(), classes_scores1.end());int idMax max_class_score - classes_scores1.begin();//cout 类别的分数值 *max_class_score id idMax endl;if (*max_class_score scoreThreshold){confidences1.push_back(confidence1);class_ids1.push_back(idMax);//前4行对应的物体的x、y、w、h这里的x、y、w、h结果只是图像640*640的结果的要返回float x detectionMat2.atfloat(i, 0);float y detectionMat2.atfloat(i, 1);float w detectionMat2.atfloat(i, 2);float h detectionMat2.atfloat(i, 3);//将x、y、w、h结果返回由640*640的结果返回到原图size大小的结果int left int((x - 0.5 * w) * x_factor1);//x_factor1*xint top int((y - 0.5 * h) * y_factor1);int width int(w * x_factor1); //宽高直接*对应比列即可int height int(h * y_factor1);boxes1.push_back(Rect(left, top, width, height)); //得到最终原图对应的矩形框大小}}}cout boxes.size(): boxes1.size() endl;//NMS结果非极大值抑制有些结果是重合的此处通过nms去除vectorint nms_result; //保存对应的索引值NMSBoxes(boxes1, confidences1, scoreThreshold, nmsThreshold, nms_result);for (int i 0; i nms_result.size(); i){int idx nms_result[i];Detection result;result.class_id class_ids1[idx];result.confidence confidences1[idx];result.box boxes1[idx];output.push_back(result);}
}2.4.1方法1指针法Mat.data解析快但不易理解
//使用指针进行相关的结果解析更快速但不易理解相关取值计算过程和上方一样可以看detect2进行理解
void YOLO::detect(Mat image, vectorDetection output)
{Mat blob;auto input_image formatYolov5(image);blobFromImage(input_image, blob, 1. / 255., Size(inputWidth, inputHeight), Scalar(), true, false);//1. / 255.数据归一化图像大小变为输入格式640*640true进行通道交换false不进行切片m_net.setInput(blob);vectorMat outputs;m_net.forward(outputs, m_net.getUnconnectedOutLayersNames());//方法1、使用指针进行解析1*252006float x_factor float(input_image.cols) / inputWidth; //用于blobFromImage归一化的input_image图像/640得到对应的比例float y_factor float(input_image.rows) / inputHeight; //用于blobFromImage归一化的input_image图像/640float data (float)outputs[0].data; //获取输出结果的初始指针vectorint class_ids;vectorfloat confidences;vectorRect boxes;for (int i 0; i rows; i){float confidence data[4]; //置信度方框box的分值if (confidence confThreshold) //求置信度{float classes_scores data 5; //求类别得分//求类别得分将第一个类别后面的所有的类别作为一个mat一行(x、y、w、h、confidence、class1、class2、、、)//一行m_classNames.size()个长度Mat scores(1, m_classNames.size(), CV_32FC1, classes_scores);//求当前最大分数的类别及其索引Point class_id;double max_class_score;minMaxLoc(scores, 0, max_class_score, 0, class_id);if (max_class_score scoreThreshold){confidences.push_back(confidence);class_ids.push_back(class_id.x);//boxfloat x data[0];float y data[1];float w data[2];float h data[3];int left int((x - 0.5 * w) * x_factor);int top int((y - 0.5 * h) * y_factor);int width int(w * x_factor);int height int(h * y_factor);boxes.push_back(Rect(left, top, width, height));}}data dimensions; //data隔着对应结果类别数15x、y、w、h}//NMS结果非极大值抑制vectorint nms_result;NMSBoxes(boxes, confidences, scoreThreshold, nmsThreshold, nms_result);for (int i 0; i nms_result.size(); i){int idx nms_result[i];Detection result;result.class_id class_ids[idx];result.confidence confidences[idx];result.box boxes[idx];output.push_back(result);}
}2.5绘制结果
就是将矩形框、分值等数据绘制到对应的图像上
void YOLO::drawRect(Mat image, vectorDetection output)
{int detections output.size();for (int i 0; i detections; i){auto detection output[i];auto box detection.box;auto classId detection.class_id;const auto color colors[classId % colors.size()];rectangle(image, box, color, 3);rectangle(image, Point(box.x, box.y - 40), Point(box.x box.width, box.y), color, FILLED);string label m_classNames[classId] : to_string(output[i].confidence);putText(image, label, Point(box.x, box.y - 5), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 0), 2);}}下面是Yolov5s.onnx对应模型的结果
- 上一篇: 深圳专业做网站和seo的公司公司企业vi设计
- 下一篇: 深圳自助建站旅游 网站建设
相关文章
-
深圳专业做网站和seo的公司公司企业vi设计
深圳专业做网站和seo的公司公司企业vi设计
- 技术栈
- 2026年04月20日
-
深圳专业做公司网站王也诸葛青车文
深圳专业做公司网站王也诸葛青车文
- 技术栈
- 2026年04月20日
-
深圳专业优定软件网站建设易思腾网站建设
深圳专业优定软件网站建设易思腾网站建设
- 技术栈
- 2026年04月20日
-
深圳自助建站旅游 网站建设
深圳自助建站旅游 网站建设
- 技术栈
- 2026年04月20日
-
深圳最好的网站建设公司排名施工企业主要负责人包括
深圳最好的网站建设公司排名施工企业主要负责人包括
- 技术栈
- 2026年04月20日
-
深圳最简单的网站建设一条龙建设网站
深圳最简单的网站建设一条龙建设网站
- 技术栈
- 2026年04月20日
