yolov5 C++环境搭建
安装依赖包:
pip install onnx
模型转化:
python export.py --weights yolov5s.pt --include onnx
opencv版本要求:4.5以上
安装部署器:opencv 4.8.0
opencv编译下载:
git clone https://github.com/opencv/opencv.git
cd opencv git checkout 4.8.0 mkdir build cd build cmake -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D OPENCV_GENERATE_PKGCONFIG=ON \ -D BUILD_EXAMPLES=OFF \ -D BUILD_TESTS=OFF \ -D BUILD_PERF_TESTS=OFF \ .. make -j$(nproc) sudo make install代码:
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) project(yolov5_cpp) set(CMAKE_CXX_STANDARD 11) set(OpenCV_DIR /usr/local/lib/cmake/opencv4) find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) add_executable(yolo main.cpp) target_link_libraries(yolo ${OpenCV_LIBS})main.cpp
#include <opencv2/opencv.hpp> #include <vector> #include <string> using namespace cv; using namespace cv::dnn; using namespace std; const float CONF_THRESHOLD = 0.25f; const float NMS_THRESHOLD = 0.45f; // 去重框关键 vector<string> class_names = { "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" }; int main() { string model_path = "yolov5s.onnx"; Net net = readNet(model_path); Mat img = imread("bus.jpg"); int h = img.rows; int w = img.cols; Mat blob = blobFromImage(img, 1 / 255.0, Size(640, 640), Scalar(), true, false); net.setInput(blob); Mat pred; net.forward(pred, net.getUnconnectedOutLayersNames()[0]); vector<Rect> boxes; vector<float> confs; vector<int> classIds; float* data = (float*)pred.data; for (int i = 0; i < 25200; i++) { float conf = data[4]; if (conf < CONF_THRESHOLD) { data += 85; continue; } Mat scores(1, class_names.size(), CV_32FC1, data + 5); double maxScore; Point maxClassPoint; minMaxLoc(scores, 0, &maxScore, 0, &maxClassPoint); int classId = maxClassPoint.x; float x = data[0]; float y = data[1]; float ww = data[2]; float hh = data[3]; int x1 = (x - ww / 2) * w / 640; int y1 = (y - hh / 2) * h / 640; int w2 = ww * w / 640; int h2 = hh * h / 640; boxes.push_back(Rect(x1, y1, w2, h2)); confs.push_back(conf); classIds.push_back(classId); data += 85; } // ✅ NMS 去重框(关键!!!) vector<int> indices; NMSBoxes(boxes, confs, CONF_THRESHOLD, NMS_THRESHOLD, indices); // ✅ 最终干净画框 for (int idx : indices) { Rect box = boxes[idx]; int cid = classIds[idx]; float cf = confs[idx]; rectangle(img, box, Scalar(0, 255, 0), 2); string label = class_names[cid] + " " + to_string(cf).substr(0, 4); putText(img, label, Point(box.x, box.y - 10), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 2); } imshow("YOLOv5 C++ 干净版", img); waitKey(0); return 0; }编译运行
mkdir build cd build cmake .. make ./yolo把图片和onnx都放到build的文件夹里,与可执行文件yolo一个目录。
