yolo.h

#pragma once
#pragma once
#include<iostream>
#include<opencv2/opencv.hpp>#define YOLO_P6 false //是否使用P6模型struct Output {int id;             //结果类别idfloat confidence;   //结果置信度cv::Rect box;       //矩形框};class Yolo {
public:Yolo() {}~Yolo() {}bool readModel(cv::dnn::Net& net, std::string& netPath, bool isCuda); //读取模型bool Detect(cv::Mat& SrcImg, cv::dnn::Net& net, std::vector<Output>& output); //前向传播void drawPred(cv::Mat& img, std::vector<Output> result, std::vector<cv::Scalar> color); //绘制矩形框void PathDB(std::string image_path, std::string imwrite_path, std::string xmlpath); //读取以及存放路径void CreateXml(const char* img_name, const char* img_path, int img_width, int img_heigh, int check_number, std::string xmlpath); //, const char* object_name, int xmin, int ymin, int xmax, int ymax,std::string xmlpath
private:
#if(defined YOLO_P6 && YOLO_P6==true)const float netAnchors[4][6] = { { 19,27, 44,40, 38,94 },{ 96,68, 86,152, 180,137 },{ 140,301, 303,264, 238,542 },{ 436,615, 739,380, 925,792 } };const int netWidth = 1280;  //ONNX图片输入宽度const int netHeight = 1280; //ONNX图片输入高度const int strideSize = 4;  //stride size
#elseconst float netAnchors[3][6] = { { 10,13, 16,30, 33,23 },{ 30,61, 62,45, 59,119 },{ 116,90, 156,198, 373,326 } };const int netWidth = 640;   //ONNX图片输入宽度const int netHeight = 640;  //ONNX图片输入高度const int strideSize = 3;   //stride size
#endif // YOLO_P6const float netStride[4] = { 8, 16.0,32,64 };float boxThreshold = 0.7;float classThreshold = 0.7;float nmsThreshold = 0.40;float nmsScoreThreshold = boxThreshold * classThreshold;//std::vector<std::string> className = { "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" };  //COCO数据集类别std::vector<std::string> className = { "worter","open","unslot","broken","people","openwin","nocap" };  //铁路数据集类别/*std::vector<std::string> className = { "element"};*/
};

yolo.cpp

#include <iostream>
#include"yolo.h"
#include "tinystr.h";
#include "tinyxml.h";
#include <list>
using namespace std;
using namespace cv;
using namespace cv::dnn;bool Yolo::readModel(Net& net, string& netPath, bool isCuda = true) {try {net = readNet(netPath);}catch (const std::exception&) {return false;}//cudaif (isCuda) {net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA_FP16);}//cpuelse {net.setPreferableBackend(cv::dnn::DNN_BACKEND_DEFAULT);net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);}return true;
}
bool Yolo::Detect(Mat& SrcImg, Net& net, vector<Output>& output) {Mat blob;int col = SrcImg.cols;int row = SrcImg.rows;int maxLen = MAX(col, row);Mat netInputImg = SrcImg.clone();if (maxLen > 1.2 * col || maxLen > 1.2 * row) {Mat resizeImg = Mat::zeros(maxLen, maxLen, CV_8UC3);SrcImg.copyTo(resizeImg(Rect(0, 0, col, row)));netInputImg = resizeImg;}blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(netWidth, netHeight), cv::Scalar(0, 0, 0), true, false);//如果在其他设置没有问题的情况下但是结果偏差很大,可以尝试下用下面两句语句//blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(netWidth, netHeight), cv::Scalar(104, 117, 123), true, false);//blobFromImage(netInputImg, blob, 1 / 255.0, cv::Size(netWidth, netHeight), cv::Scalar(114, 114,114), true, false);net.setInput(blob);std::vector<cv::Mat> netOutputImg;net.forward(netOutputImg, net.getUnconnectedOutLayersNames());std::vector<int> classIds;//结果id数组std::vector<float> confidences;//结果每个id对应置信度数组std::vector<cv::Rect> boxes;//每个id矩形框float ratio_h = (float)netInputImg.rows / netHeight;float ratio_w = (float)netInputImg.cols / netWidth;int net_width = className.size() + 5;  //输出的网络宽度是类别数+5float* pdata = (float*)netOutputImg[0].data;for (int stride = 0; stride < strideSize; stride++) {    //strideint grid_x = (int)(netWidth / netStride[stride]);int grid_y = (int)(netHeight / netStride[stride]);for (int anchor = 0; anchor < 3; anchor++) {    //anchorsconst float anchor_w = netAnchors[stride][anchor * 2];const float anchor_h = netAnchors[stride][anchor * 2 + 1];for (int i = 0; i < grid_y; i++) {for (int j = 0; j < grid_x; j++) {float box_score = pdata[4]; ;//获取每一行的box框中含有某个物体的概率if (box_score >= boxThreshold) {cv::Mat scores(1, className.size(), CV_32FC1, pdata + 5);Point classIdPoint;double max_class_socre;minMaxLoc(scores, 0, &max_class_socre, 0, &classIdPoint);max_class_socre = (float)max_class_socre;if (max_class_socre >= classThreshold) {//rect [x,y,w,h]float x = pdata[0];  //xfloat y = pdata[1];  //yfloat w = pdata[2];  //wfloat h = pdata[3];  //hint left = (x - 0.5 * w) * ratio_w;int top = (y - 0.5 * h) * ratio_h;classIds.push_back(classIdPoint.x);confidences.push_back(max_class_socre * box_score);boxes.push_back(Rect(left, top, int(w * ratio_w), int(h * ratio_h)));}}pdata += net_width;//下一行}}}}//执行非最大抑制以消除具有较低置信度的冗余重叠框(NMS)vector<int> nms_result;NMSBoxes(boxes, confidences, nmsScoreThreshold, nmsThreshold, nms_result);for (int i = 0; i < nms_result.size(); i++) {int idx = nms_result[i];Output result;result.id = classIds[idx];result.confidence = confidences[idx];result.box = boxes[idx];output.push_back(result);}
}                        // 图片名字            绝对路径         宽度            高度                                      物体类别        x小坐标   y小坐标    x大坐标   y大坐标         保存xml路径
void Yolo::CreateXml(const char* img_name, const char* img_path, int img_width, int img_heigh, int check_number, std::string xmlpath)//const char* object_name, int xmin, int ymin, int xmax, int ymax,
{std::string a = "E:/DeployYoloV5/DeployYoloV5/1.jpg";const char* p = a.data();TiXmlDocument doc;     //创建一个文档类//创建一个描述,构造参数(version,encoding,standalone)TiXmlElement* rootElement = new TiXmlElement("annotation");      //创建一个根element rootTiXmlElement* PersonElement = new TiXmlElement("image");TiXmlElement* PersonElement2 = new TiXmlElement("img_size");rootElement->LinkEndChild(PersonElement);rootElement->LinkEndChild(PersonElement2);PersonElement->SetAttribute("img_name", img_name);PersonElement->SetAttribute("img_path", img_path);PersonElement2->SetAttribute("width", img_width);PersonElement2->SetAttribute("height", img_heigh);TiXmlElement* PersonElement3 = new TiXmlElement("object");rootElement->LinkEndChild(PersonElement3);PersonElement3->SetAttribute("Check_objectnumber", check_number);/*PersonElement3->SetAttribute("name", object_name);PersonElement3->SetAttribute("xmin", xmin);PersonElement3->SetAttribute("ymin", ymin);PersonElement3->SetAttribute("xmax", xmax);PersonElement3->SetAttribute("ymax", ymax);*/doc.LinkEndChild(rootElement);//文档添加root elementstring filenamexml = ".xml";//cout << xmlpath;string totalpath = xmlpath + filenamexml; const char* path = totalpath.data();doc.SaveFile(path);//保存到文件new.xml
}void Yolo::drawPred(Mat& img, vector<Output> result, vector<Scalar> color) {for (int i = 0; i < result.size(); i++) {//cout << result.size(); //查看检测到物体的数量int left, top;left = result[i].box.x;top = result[i].box.y;int color_num = i;rectangle(img, result[i].box, color[result[i].id], 10, 8);  //在图片中划出矩形框string label = className[result[i].id] + ":" + to_string(result[i].confidence);int baseLine;Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);top = max(top, labelSize.height);putText(img, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 5, color[result[i].id], 3);}Mat dst;//resize(img, dst, Size(), 0.2, 0.3); //图片进行比例缩放//imshow("1", dst); //展示窗口//waitKey();  //窗口等待//destroyAllWindows();  // 关闭所有窗口//system("pause"); //让控制台暂停,等待用户信号
}const char* object_name[100]; //声明一个char类型用于保存类别名字
void Yolo::PathDB(string image_path, string imwrite_path, std::string xmlpath) {  // 读取模型路径  Yolo test;Net net;string model_path = "E:/yolov5-master/runs/train/exp/weights/best.onnx";if (test.readModel(net, model_path, false)) {cout << "read net ok!" << endl; }else {cout << "No found path of onnx!";}//生成随机颜色vector<Scalar> color;srand(time(0));for (int i = 0; i < 80; i++) {int b = rand() % 256;int g = rand() % 256;int r = rand() % 256;color.push_back(Scalar(b, g, r));}vector<String>src_test;vector<Output> result;Mat img = imread(image_path);glob(image_path, src_test, false);//将文件夹路径下的所有图片路径保存到src_test中if (src_test.size() == 0) {//判断文件夹里面是否有图片printf("No image in file ! Please check the folder for pictures\n");exit(1);}//aaa();for (int i = 0; i < src_test.size(); i++){Mat img = imread(src_test[i]);int pos = src_test[i].find_last_of("\\"); // 切分找到最后一个名字string imagepatht = src_test[i];const char* image_pathcc = imagepatht.data(); //传入图片绝对路径//cout << image_pathcc;string save_name = src_test[i].erase(0, pos);const char* image_name = save_name.data(); //传入图片名字cv::Mat dst;if (test.Detect(img, net, result)) {test.drawPred(img, result, color);if (result.size() > 0){               string name_xml_path = xmlpath + save_name;cout << name_xml_path;CreateXml(image_name, image_pathcc, img.rows, img.cols, result.size(), name_xml_path);   //xml生成   imwrite(imwrite_path + save_name, img);  //把有问题的图片进行保存                                                                                                // label xm ym xmax ymax}result.clear(); // 对每次循环检测到图片信息的结果进行一次清除img.release(); //释放资源}else{cout << "Detect Failed!" << endl;}continue;}}

YoloSave.cpp

// YoloSave.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include "yolo.h";
#include <iostream>
#include<opencv2//opencv.hpp>
#include<math.h>using namespace std;
using namespace cv;
using namespace dnn;
int main(int argc, char* argv[]) //argc 总参数个数  argv[]是arcg个参数
{Yolo path;/*cout << "参数个数:" << argc << endl;cout << "参数内容:";*/for (int i = 0; i < argc; ++i){cout << argv[i] << endl;}cout << "=============="<<endl;string str1 = argv[1];string str2 = argv[2];string str3 = argv[3];//cout << str1 << endl;//cout << str2 << endl;//cout << str3 << endl;path.PathDB(str1,str2,str3); //image_path, imwrite_path, svacexml_path//system("pause");return 0;
}// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单// 入门使用技巧:
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

#############################################################################

其余的头文件与源文件为xml提供的

需要传3个string类型的参数:

cmd命令行输入:

YoloSave.exe E:/yolov5-master/image_test E:/DeployYoloV5/YoloSave/outputimg E:/DeployYoloV5/YoloSave\outxml

查看结果:

这两个文件夹中生成了对应的检测到有问题的图片以及对应的xml

opencv部署onnx,并对jpg图片进行批量检测生成xml重要信息相关推荐

  1. 使用OpenVINO部署ONNX模型

    做深度学习神经网络的设计.训练与部署,往往会困扰于不同的操作系统,不同的深度学习框架,不同的部署硬件,以及不同的版本.由于相互之间的不兼容,给开发使用者造成了很大的不便. 联合使用OpenVINO和O ...

  2. 关于opencv调用onnx模型的一个错误 Can’t infer a dim denoted by -1 in function ‘cv::dnn::computeShapeByReshapeMas

    关于opencv调用onnx模型的一个错误 Can't infer a dim denoted by -1 in function 'cv::dnn::computeShapeByReshapeMas ...

  3. 开个坑,libtorch1.5 + opencv部署

    开个坑,libtorch + opencv部署 libtorch1.5部署windows平台的深度学习应用 libtorch想说production不容易 python opencv 与 c++ op ...

  4. OpenCV推断onnx格式目标检测模型(SSD)(附完整代码)

    OpenCV推断onnx格式目标检测模型的实例 OpenCV推断onnx格式目标检测模型的实例 OpenCV推断onnx格式目标检测模型的实例 #include <algorithm> # ...

  5. AI 质检学习报告——实践篇——第三步:python利用OpenCV打开摄像头截图后实现图片识字

    AI 质检学习报告--实践篇--第一步:python利用OpenCV打开摄像头并截图 AI 质检学习报告--实践篇--第二步:实现图片识字 前边两篇实践已经分别实现了利用OpenCV打开摄像头并截图和 ...

  6. 使用openCV 的cv2.imread函数读取图片找不到路径

    使用openCV 的cv2.imread函数读取图片时出现,找不到图像的问题: 错误如下: 尝试把 \ 换为 /, 或者把 \ 换为 \ 都不可以. 后来发现,是中文路径的问题,将中文路径换为英文路径 ...

  7. OpenCV输出图像到文件:imwrite()函数。在OpenCV中生成一幅png图片,并写入当前工程目录

    关于VS下OpenCV的配置.可见如下链接: OpenCV的安装与实现VS环境设置 在OpenCV中,输入图像到文件一般采用imwrite函数,它的声明如下: CV_EXPORTS_W bool im ...

  8. php 图片填充颜色代码,PHP获取图片颜色值,检测图片主要颜色的代码:

    $i=imagecreatefromjpeg("photo3.jpg");//测试图片,自己定义一个,注意路径 for ($x=0;$x for ($y=0;$y $rgb = i ...

  9. 图片的批量下载 和 爬虫爬取图片数据集

    图片的批量下载 和 爬虫爬取图片数据集 1.图片的批量下载 1.图片的批量下载 数据集是深度学习的一切,没有数据集它什么也不是,现在你知道数据集很重要了吧 代码: ''' 项目名称:爬取公章数据 创建 ...

  10. OpenCV学习(二十四 ):角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack()

    OpenCV学习(二十四 ):角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack() 参考博客: Harris角点检测原理详解 Harri ...

最新文章

  1. Android 程序自动更新功能模块实现
  2. Coding:C++类定义实现部分成员函数
  3. Centos7 安装 opencv
  4. tps+qps+mysql_实时获取MySQL的TPS、QPS(输出到屏幕)
  5. window.onload=function(){};
  6. camera(21)---MTK android AF调试总结
  7. Visual Studio开发工具(5):VS2010 精美壁纸,总有一款适合你!
  8. JavaWeb——jdbc与dbcp数据库连接
  9. linux下oracle登陆建表,Oracle建表过程初学
  10. 开放平台及其技术架构
  11. php allow origin,Allow-Control-Allow-Origin:谷歌跨域扩展插件
  12. 虚拟机web服务器安装与配置,实验Web服务器的安装与配置.doc
  13. 【002】龙芯CPU实时系统解决方案
  14. (短除法)求两个给定正整数的最大公约数和最小公倍数。
  15. 微软面试题 博弈论 经典案例 (参考答案)
  16. 专科计算机网络技术综述,高职高专计算机系列教材:计算机网络技术
  17. 真实场景的双目立体匹配(Stereo Matching)获取深度图详解
  18. 克劳士比语录(转载)
  19. 藤子不二雄博物馆之行
  20. [2010年终大礼]破壳而出的琉璃之鸟 汉化补丁 第二版

热门文章

  1. GPU编程3--GPU内存深入了解
  2. 南阳oj题目20吝啬的国度 菜鸟的进阶之路
  3. 如何拆分PDF成单页?这三个方法分享给你
  4. go 获取是第几周_golang判断当前时间是第几周的方法
  5. 【网络安全】DRIDEX木马巧用VEH混淆API调用流程
  6. 微信小程序:we重师
  7. Font Awesome 找图标的正确姿势
  8. 大数据时代,数据的应用场景
  9. Windows 11的临时文件清理工具
  10. Android仿人人客户端(v5.7.1)——新鲜事之完整篇