专栏名称: OpenCV学堂
一个致力于计算机视觉OpenCV原创技术传播的公众号!OpenCV计算机视觉与tensorflow深度学习相关算法原创文章分享、函数使用技巧、源码分析与讨论、,计算机视觉前沿技术介绍,技术专家经验分享,人才交流,学习交流。
目录
相关文章推荐
一条漫画  ·  男友的口味,让我很不舒服 ·  昨天  
一条漫画  ·  姐那么优秀,我怎么舍得离开她 ·  昨天  
蜂鸟摄影  ·  被内涵了!“Yes, But” ... ·  昨天  
Kane的小K屋  ·  当AI说:"你不配活着" ·  2 天前  
51好读  ›  专栏  ›  OpenCV学堂

OpenCV4.8 + YOLO11 C++ 部署推理

OpenCV学堂  · 公众号  ·  · 2024-12-25 17:14

正文

点击上方 蓝字 关注我们

微信公众号: OpenCV学堂

关注获取更多计算机视觉与深度学习知识

自从 YOLOv5 更新成 7.0 版本, YOLOv8、YOLO11 推出以后, OpenCV4.6 以前的版本都无法再加载导出 ONNX 格式模型了,只有 OpenCV4.7 以上版本才可以支持最新版本 YOLOv5、YOLOv8、YOLO11 模型的推理部署。首先看一下最新版本的 YOLO11 的输入与输出格式:

就会发现,跟YOLOv8输入与输出结果完全一致,没有什么改变。

推理演示截图:

代码已经全部测试过了,可以直接调用:

  1. #include

  2. #include

  3. #include

  4. std::string label_map = "D:/python/yolov5-7.0/classes.txt";

  5. int main(int argc, char** argv) {

  6. std::vector<std::string> classNames;

  7. std::ifstream fp(label_map);

  8. std::string name;

  9. while (!fp.eof()) {

  10. getline(fp, name);

  11. if (name.length ()) {

  12. classNames.push_back(name);

  13. }

  14. }

  15. fp.close();

  16. std::vector<cv::Scalar> colors;

  17. colors.push_back(cv::Scalar(0, 255, 0));

  18. colors.push_back(cv::Scalar(0, 255, 255));

  19. colors.push_back(cv::Scalar(255, 255, 0));

  20. colors.push_back(cv::Scalar(255, 0, 0));

  21. colors.push_back(cv::Scalar(0, 0, 255));

  22. std::string onnxpath = "D:/projects/yolov8n.onnx";

  23. auto net = cv::dnn::readNetFromONNX(onnxpath);

  24. net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);

  25. net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);

  26. cv ::VideoCapture capture("D:/images/video/sample.mp4");

  27. cv::Mat frame;

  28. while (true) {

  29. bool ret = capture.read(frame);

  30. if (frame.empty()) {

  31. break;

  32. }

  33. int64 start = cv::getTickCount();

  34. // 图象预处理 - 格式化操作

  35. int w = frame.cols;

  36. int h = frame.rows;

  37. int _max = std::max(h, w);

  38. cv::Mat image = cv::Mat::zeros(cv::Size(_max, _max), CV_8UC3);

  39. cv::Rect roi(0, 0, w, h);

  40. frame.copyTo(image(roi));

  41. float x_factor = image.cols / 640.0f;

  42. float y_factor = image.rows / 640.0f;

  43. // 推理

  44. cv::Mat blob = cv::dnn::blobFromImage(image, 1 / 255.0, cv::Size(640, 640), cv::Scalar(0, 0, 0), true, false);

  45. net.setInput(blob);

  46. cv::Mat preds = net.forward();

  47. // 后处理, 1x84x8400

  48. cv::Mat outs(preds.size[1], preds.size[2], CV_32F, preds.ptr());

  49. cv::Mat det_output = outs.t();

  50. float confidence_threshold = 0.5;

  51. std::vector<cv::Rect> boxes;

  52. std::vector classIds;

  53. std::vector confidences;

  54. for (int i = 0; i < det_output.rows; i++) {

  55. cv::Mat classes_scores = det_output.row(i ).colRange(4, preds.size[1]);

  56. cv::Point classIdPoint;

  57. double score;

  58. minMaxLoc(classes_scores, 0, &score, 0, &classIdPoint);

  59. // 置信度 0~1之间

  60. if (score > 0.25)

  61. {

  62. float cx = det_output.at(i, 0);

  63. float cy = det_output.at(i, 1);

  64. float ow = det_output.at(i, 2);

  65. float oh = det_output.at(i, 3);

  66. int x = static_cast((cx - 0.5 * ow) * x_factor);

  67. int y = static_cast((cy - 0.5 * oh) * y_factor);

  68. int width = static_cast(ow * x_factor);

  69. int height = static_cast(oh * y_factor);

  70. cv::Rect box;

  71. box.x = x;

  72. box.y = y;

  73. box.width = width;

  74. box.height = height;

  75. boxes.push_back(box);

  76. classIds.push_back(classIdPoint.x);

  77. confidences.push_back(score);

  78. }

  79. }

  80. // NMS

  81. std::vector indexes;

  82. cv::dnn::NMSBoxes(boxes, confidences, 0.25, 0.50, indexes);

  83. for (size_t i = 0; i < indexes.size(); i++) {

  84. int index = indexes[i];

  85. int idx = classIds[index];

  86. cv::rectangle(frame, boxes[index], colors[idx % 5], 2, 8);

  87. cv::rectangle(frame, cv::Point(boxes[index].tl().x, boxes[index].tl().y - 20),

  88. cv::Point(boxes[index].br().x, boxes[index].tl().y), cv::Scalar(255, 255, 255), -1);

  89. cv::putText(







请到「今天看啥」查看全文