基于C++和ONNX Runtime部署YOLOv12的ONNX模型,可以遵循以下步驟:
-
準備環境:首先,確保已經下載后指定版本opencv和onnruntime的C++庫。
-
模型轉換:?安裝好yolov12環境并將YOLOv12模型轉換為ONNX格式。這通常涉及使用深度學習框架(如PyTorch或TensorFlow)加載原始模型,并導出為ONNX格式。轉換指令
# End-to-End ONNX
yolo export model=yolov12{n/s/m/b/l/x}.pt format=onnx opset=13 simplify
-
C++環境配置:在CMakeLists.txt項目中正確引用了opencv和ONNX Runtime的頭文件,并鏈接到相應的庫。這允許在C++代碼中使用ONNX Runtime的功能。
-
加載模型:使用ONNX Runtime的API加載轉換后的YOLOv12 ONNX模型。
-
執行推理:通過ONNX Runtime的推理引擎,將圖像數據輸入到模型中,并執行目標檢測任務。
-
處理結果:解析模型輸出的結果,這通常涉及將輸出的張量數據轉換為可理解的檢測結果,如邊界框坐標和類別標簽。
通過這些步驟,可以在C++環境中利用ONNX Runtime高效地部署YOLOv12模型,實現實時的目標檢測功能。
【測試環境】
windows10 x64
vs2019
cmake==3.30.1
onnxruntime==1.16.3
opencv==4.9.0
【使用步驟】
首先cmake生成exe文件,然后將onnxruntime.dll和onnxruntime_providers_shared.dll放到exe一起,不然會提示報錯0xc000007b,這是因為系統目錄也有個onnxruntime.dll引發沖突,并把car.mp4也放到exe一起。運行直接輸入
yolov12.exe?注意onnx路徑要是你真實路徑我的onnx路徑是我桌面上地址
【代碼調用】
注意onnxruntime使用的cpu版本庫,如需使用GPU還需要修改代碼才行
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <iostream>
#include <string>
#include "YOLO12.hpp"int main() {// Paths to the model, labels, test image, and save directoryconst std::string labelsPath = "../models/coco.names";const std::string imagePath = "../data/dog.jpg"; // Image pathconst std::string savePath = "../data/dog_detections.jpg"; // Save directory// Model path for YOLOv12const std::string modelPath = "../models/yolov12n.onnx"; // YOLOv12// Initialize the YOLO detector with the chosen model and labelsbool isGPU = true; // Set to false for CPU processingYOLO12Detector detector(modelPath, labelsPath, isGPU);// Load an imagecv::Mat image = cv::imread(imagePath);if (image.empty()) {std::cerr << "Error: Could not open or find the image!\n";return -1;}// Detect objects in the image and measure execution timeauto start = std::chrono::high_resolution_clock::now();std::vector<Detection> results = detector.detect(image);auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start);std::cout << "Detection completed in: " << duration.count() << " ms" << std::endl;// Draw bounding boxes on the imagedetector.drawBoundingBox(image, results); // Simple bounding box drawing// detector.drawBoundingBoxMask(image, results); // Uncomment for mask drawing// Save the processed image to the specified directoryif (cv::imwrite(savePath, image)) {std::cout << "Processed image saved successfully at: " << savePath << std::endl;} else {std::cerr << "Error: Could not save the processed image to: " << savePath << std::endl;}// Display the imagecv::imshow("Detections", image);cv::waitKey(0); // Wait for a key press to close the windowreturn 0;
}
部署演示可以參考視頻:bilibili.com/video/BV1iYPsewEDg