小言_互联网的博客

yolov5 opencv DNN 推理

573人阅读  评论(0)

一、环境

opencv4.5.1

Ubuntu 21.10

二、onnx转换

切换到yolov5工程中,打开终端运行指令

python export.py --weights yolov5s.pt --include onnx

onnx转onnx-sim

python -m onnxsim yolov5s.onnx yolov5s_sim.onnx

使用netron打开onnx文件

 最终的输出1*25200*85,将三个输出整合在一起即:

 25200=3*(20*20)+3*(40*40)+3*(80*80)个候选框

三、python版本推理

opecv DNN API:
1.读取模型
net = cv2.dnn.readNetFromONNX(model)
2.输入(类似Tensor)
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (640, 640), swapRB=True, crop=False)
        swapRB:BGR->RGB
net.setInput(blob)
3.推理
preds = net.forward()
4.非极大值抑制
cv2.dnn.NMSBoxes(boxes,confidences,0.25,0.45)


  
  1. import cv2
  2. import numpy as np
  3. classes=[ "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
  4. "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
  5. "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
  6. "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
  7. "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
  8. "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
  9. "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone",
  10. "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear",
  11. "hair drier", "toothbrush"]
  12. def infer( img,pred,shape):
  13. w_ratio=img.shape[ 1]/shape[ 0]
  14. h_ratio=img.shape[ 0]/shape[ 1]
  15. # print(w_ratio,h_ratio)
  16. confidences=[]
  17. boxes=[]
  18. class_ids=[]
  19. boxes_num=pred.shape[ 1]
  20. data=pred[ 0]
  21. # print("data_shape:",data.shape)
  22. for i in range(boxes_num):
  23. da=data[i] #[box,conf,cls]
  24. confidence=da[ 4]
  25. if confidence> 0.6:
  26. score=da[ 5:]*confidence
  27. _,_,_,max_score_index=cv2.minMaxLoc(score) #
  28. max_cls_id=max_score_index[ 1]
  29. if score[max_cls_id]> 0.25:
  30. confidences.append(confidence)
  31. class_ids.append(max_cls_id)
  32. x,y,w,h=da[ 0].item(),da[ 1].item(),da[ 2].item(),da[ 3].item()
  33. nx= int((x-w/ 2.0)*w_ratio)
  34. ny= int((y-h/ 2.0)*h_ratio)
  35. nw= int(w*w_ratio)
  36. nh= int(h*h_ratio)
  37. boxes.append(np.array([nx,ny,nw,nh]))
  38. indexes=cv2.dnn.NMSBoxes(boxes,confidences, 0.25, 0.45)
  39. res_ids=[]
  40. res_confs=[]
  41. res_boxes=[]
  42. for i in indexes:
  43. res_ids.append(class_ids[i])
  44. res_confs.append(confidences[i])
  45. res_boxes.append(boxes[i])
  46. # print(res_ids)
  47. # print(res_confs)
  48. # print(res_boxes)
  49. return res_ids,res_confs,res_boxes
  50. def draw_rect( img,ids,confs,boxes):
  51. for i in range( len(ids)):
  52. cv2.rectangle(img, boxes[i], ( 0, 0, 255), 2)
  53. cv2.rectangle(img, (boxes[i][ 0],boxes[i][ 1]- 20),(boxes[i][ 0]+boxes[i][ 2],boxes[i][ 1]), ( 200, 200, 200), - 1)
  54. cv2.putText(img, classes[ids[i]], (boxes[i][ 0], boxes[i][ 1] - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, ( 255, 0, 0))
  55. cv2.putText(img, str(confs[i]), (boxes[i][ 0]+ 60, boxes[i][ 1] - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, ( 255, 0, 0))
  56. cv2.imwrite( "res.jpg",img)
  57. cv2.imshow( 'img',img)
  58. cv2.waitKey()
  59. if __name__== "__main__":
  60. import time
  61. st=time.time()
  62. shape=( 640, 640)
  63. src=cv2.imread( "../data/bus.jpg")
  64. img=src.copy()
  65. net=cv2.dnn.readNet( "../model_m1/yolov5s_sim.onnx")
  66. blob=cv2.dnn.blobFromImage(img, 1/ 255.,shape,swapRB= True,crop= False)
  67. net.setInput(blob)
  68. pred=net.forward()
  69. print(pred.shape)
  70. ids,confs,boxes=infer(img,pred,shape)
  71. et=time.time()
  72. print( "run time:{:.2f}s/{:.2f}FPS". format(et-st, 1/(et-st)))
  73. draw_rect(src,ids,confs,boxes)

运行结果:

四、C++ 版本推理

cdnn.cpp


  
  1. #include<iostream>
  2. #include<opencv2/imgproc.hpp>
  3. #include<opencv2/opencv.hpp>
  4. void infer_res(cv::Mat& img,cv::Mat& preds,std::vector<cv::Rect> &boxes,std::vector< float>&confidences,std::vector< int> &classIds,std::vector< int>&indexs)
  5. {
  6. float w_ratio=img.cols/ 640.0;
  7. float h_ratio=img.rows/ 640.0;
  8. cv::Mat data(preds.size[ 1],preds.size[ 2],CV_32F,preds.ptr< float>());
  9. for( int i= 0;i<data.rows;i++)
  10. {
  11. float conf=data.at< float>(i, 4);
  12. if(conf< 0.45)
  13. {
  14. continue;
  15. }
  16. cv::Mat clsP=data.row(i).colRange( 5, 85)*conf;
  17. cv::Point IndexId;
  18. double score;
  19. minMaxLoc(clsP, 0,&score, 0,&IndexId);
  20. if(score> 0.25)
  21. {
  22. float x=data.at< float>(i, 0);
  23. float y=data.at< float>(i, 1);
  24. float w=data.at< float>(i, 2);
  25. float h=data.at< float>(i, 3);
  26. int nx= int((x-w/ 2.0)*w_ratio);
  27. int ny= int((y-h/ 2.0)*h_ratio);
  28. int nw= int(w*w_ratio);
  29. int nh= int(h*h_ratio);
  30. cv::Rect box;
  31. box.x=nx;
  32. box.y=ny;
  33. box.width=nw;
  34. box.height=nh;
  35. boxes.push_back(box);
  36. classIds.push_back(IndexId.x);
  37. confidences.push_back(score);
  38. }
  39. }
  40. // std::vector<int>indexs;
  41. cv::dnn::NMSBoxes(boxes,confidences, 0.25, 0.45,indexs);
  42. }
  43. //void draw_label(cv::Mat& img,std::vector<cv::Rect> &boxes,std::vector<float>&confidences,std::vector<int> &classIds,std::vector<int>&indexs,std::string& classes[])
  44. //{
  45. // for(int i=0;i<boxes.size();i++)
  46. // {
  47. // cv::rectangle(img,boxes[i],(0,0,0),1);
  48. //
  49. // }
  50. // cv::imshow("img",img);
  51. // cv::waitKey();
  52. //
  53. //}
  54. int main()
  55. {
  56. clock_t st=clock();
  57. cv::Mat src=cv::imread( "../../data/bus.jpg");
  58. std::string classNames[]={ "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
  59. "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
  60. "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
  61. "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
  62. "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
  63. "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
  64. "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone",
  65. "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear",
  66. "hair drier", "toothbrush"};
  67. cv::Mat img=src. clone();
  68. cv::dnn::Net net=cv::dnn::readNet( "../../model_m1/yolov5s_sim.onnx");
  69. cv::Mat blob=cv::dnn::blobFromImage(img, 1/ 255.0,cv::Size( 640, 640), cv::Scalar( 0, 0, 0), true, false);
  70. net.setInput(blob);
  71. cv::Mat preds=net.forward();
  72. std::vector<cv::Rect>boxes;
  73. std::vector< float>confidences;
  74. std::vector< int> classIds;
  75. std::vector< int>indexs;
  76. infer_res(src,preds,boxes,confidences,classIds,indexs);
  77. clock_t et=clock();
  78. std::cout<< "run time:"<<( double)(et-st)/CLOCKS_PER_SEC<<std::endl;
  79. // draw_label(img,boxes,confidences,classIds,indexs,&classNames);
  80. for( int i= 0;i<indexs.size();i++)
  81. {
  82. cv::rectangle(src,boxes[indexs[i]],( 0, 0, 255), 2);
  83. cv::rectangle(src,cv::Point(boxes[indexs[i]].tl().x,boxes[indexs[i]].tl().y- 20),
  84. cv::Point(boxes[indexs[i]].tl().x+boxes[indexs[i]].br().x,boxes[indexs[i]].tl().y),cv::Scalar( 200, 200, 200),- 1);
  85. cv::putText(src,classNames[classIds[indexs[i]]], cv::Point(boxes[indexs[i]].tl().x+ 5, boxes[indexs[i]].tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .5, cv::Scalar( 0, 0, 0));
  86. std::ostringstream conf;
  87. conf<<confidences[indexs[i]];
  88. cv::putText(src,conf.str(), cv::Point(boxes[indexs[i]].tl().x+ 60, boxes[indexs[i]].tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .5, cv::Scalar( 0, 0, 0));
  89. }
  90. cv::imwrite( "res_.jpg",src);
  91. cv::imshow( "img",src);
  92. cv::waitKey();
  93. return 0;
  94. }

CMakeLists.txt


  
  1. cmake_minimum_required(VERSION 2.8)
  2. project (cdnn)
  3. find_package (OpenCV 4.5.1 REQUIRED)
  4. include_directories (${OpenCV_INCLUDES_DIRS})
  5. add_executable (cdnn cdnn.cpp)
  6. target_link_libraries (cdnn ${OpenCV_LIBS})

执行:


  
  1. mkdir build
  2. cd build
  3. cmake ..
  4. make
  5. ./cdnn

运行结果:


转载:https://blog.csdn.net/m0_37264397/article/details/125791308
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场