一、配置OpenCV
1、下载OpenCV4.8.0
官网地址:https://opencv.org/,在Library中找到Releases,进入下载界面
点击windows完成下载
2、安装OpenCV
选择好相应的路径后,点击Extract,等待后完成
二、配置VS2022
1、下载 Visual Studio Installer
官网地址:https://visualstudio.microsoft.com/zh-hans/downloads/,选择社区版进行下载
下载并安装后,
我只使用到C++桌面开发组件,其他组件按需勾选
注意:一定要修改安装位置,改到空间充裕的盘
其中共享组件的修改方法(参考下面的博客)
Win + R + regedit
,找到
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\Setup
找到 SharedInstallationPath
, 将 “数值数据”一项,修改为自己的路径
关闭 “Visual Studio Installer”, 并重新打开进行安装,发现路径已修改了
等待安装完后即可
三、配置CUDA11.8
首先查看自己电脑可安装CUDA的最高版本,点击cmd,在命令行里输入nvidia-smi.exe
我的最高版本可装CUDA12.6
我选择的版本是CUDA11.8
打开官网 https://developer.nvidia.com/cuda-toolkit-archive
选择对应的版本,点击Download下载
注意:window10的在Version处要选择10,window11则选择11
安装过程尽量不要修改路径,避免安装失败
安装好后打开环境变量,检查是否有安装路径
在命令行运行nvcc -V,若出现下面的提示则表示运行成功
四、配置CUDNN8.8.1
下载网址 https://developer.nvidia.com/rdp/cudnn-archive,笔者选择的版本是8.8.1
选择
下载完成解压缩后,将对应的文件夹中的lib,include,bin文件夹复制到CUDA目录下的
然后在系统环境变量中添加如下路径
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\include
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\lib
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\libnvvp
测试CUDA和CUDNN是否安装成功
在该文件夹C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\extras\demo_suite中找到 bandwidtTest.exe 和 devicxeQuery.exe,分别在终端中运行,如果出现Result = Pass表示成功安装
五、安装 onnxruntime-gpu v1.18.1
下载网址 https://github.com/microsoft/onnxruntime/releases
进入后选择,下载后解压缩即可
六、下载 ultralytics-main(YOLO)
进入 https://github.com/ultralytics/ultralytics,点击Download ZIP
下载完成后,训练好自己的模型,具体训练方法不过多介绍
生成.pt文件并转换为.onnx格式,参考下面的代码
from ultralytics import YOLO
# 加载模型
model = YOLO("your/weight/path") # 加载预训练模型或自定义训练模型
# 导出模型为 ONNX 格式
model.export(format="onnx")
七、配置VS环境(重头戏)
参考博客原址:
(轮椅教程)使用cpp部署yolov8官方案例1[windows + vs + onnxruntime-gpu]_yolov8+reid cpp-优快云博客
1、将安装好的 opencv,onnxruntime-win-x64-gpu-1.18.1,ultralytics-main放到同一个文件夹下,打开VS创建一个空项目。
2、打开Visual Studio 创建一个新项目,并将项目位置放在和上面同一文件夹下
3、将屏幕上方的 Debug 模式改为 Release
4、在源文件和头文件中将 ultralytics-main\examples\YOLOv8-ONNXRuntime-CPP 该路径下的main.cpp,inference.cpp,inference.h 复制进项目中
5、右键 解决方案资源管理器下的项目,选择其中的 属性
6、选择 C++语言标准 为 C++17
7、C/C++ -> 常规 ->附加包含目录,输入下列路径(要根据自己文件夹的路径修改)
F:\opencv_cuda\onnxruntime-win-x64-gpu-1.18.1\include
F:\opencv_cuda\opencv\build\include
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\include
8、链接器 -> 常规 -> 附加库目录,输入下列路径
F:\opencv_cuda\opencv\build\x64\vc16\lib
F:\opencv_cuda\onnxruntime-win-x64-gpu-1.18.1\lib
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\lib\x64
9、链接器 -> 输入 -> 附加依赖项,输入下列路径(最好打开自己的.lib文件夹查看是否有下面的.lib文件)
onnxruntime.lib
onnxruntime_providers_cuda.lib
onnxruntime_providers_shared.lib
opencv_world480.lib
10、回到主界面后点击 本地Windows调制器(报错没关系,目的是在工程文件夹中生成Release文件夹)
11、在该路径下找到 工程文件路径\x64\Release 将步骤9中的.lib文件复制进入
12、重新打开工程,找到 main.cpp 修改成如下的代码
void Detector(YOLO_V8*& p)
改为:
void Detector(YOLO_V8*& p) {
std::string img_path = "你的图片路径";
cv::Mat img = cv::imread(img_path);
std::vector<DL_RESULT> res;
p->RunSession(img, res);
for (auto& re : res)
{
cv::RNG rng(cv::getTickCount());
cv::Scalar color(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
cv::rectangle(img, re.box, color, 3);
float confidence = floor(100 * re.confidence) / 100;
std::cout << std::fixed << std::setprecision(2);
std::string label = p->classes[re.classId] + " " +
std::to_string(confidence).substr(0, std::to_string(confidence).size() - 4);
cv::rectangle(
img,
cv::Point(re.box.x, re.box.y - 25),
cv::Point(re.box.x + label.length() * 15, re.box.y),
color,
cv::FILLED
);
cv::putText(
img,
label,
cv::Point(re.box.x, re.box.y - 5),
cv::FONT_HERSHEY_SIMPLEX,
0.75,
cv::Scalar(0, 0, 0),
2
);
}
std::cout << "Press any key to exit" << std::endl;
cv::imshow("Result of Detection", img);
cv::waitKey(0);
cv::destroyAllWindows();
}
void Classifier(YOLO_V8*& p) 删掉
int ReadCocoYaml(YOLO_V8*& p) 删掉
无论有没有coco.yaml都把它删掉自己写类名,这个代码写的有问题
void DetectTest() 改为
yoloDetector->classes = { "0","1","2" };
函数中 params.modelPath = "yolov8n.onnx" 改为自己的 yolov8n.onnx 路径
void ClsTest() 删掉
int main() 改为
int main()
{
DetectTest();
}
13、打开 inference.cpp
在第一行加上 #define _CRT_SECURE_NO_WARNINGS 1
在报错的字符串前加上 (char*)
八、运行(cpu)直接运行
九、运行(cuda)
在main.cpp
第一行前加上#define USE_CUDA
十、接入摄像头
将main.cpp更改为如下代码(注意 权重文件路径 的修改和 classes标签 的修改)(第100行)
#define USE_CUDA
#include <iostream>
#include <iomanip>
#include "inference.h"
#include <filesystem>
#include <fstream>
#include <random>
#include <opencv2/opencv.hpp>
namespace fs = std::filesystem;
void DetectFromCamera(YOLO_V8*& p, const std::string& saveFolder) {
// 打开默认摄像头(设备编号为 0)
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cerr << "Error: Could not open camera." << std::endl;
return;
}
// 获取摄像头的基本信息
int frameWidth = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
int frameHeight = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
double fps = cap.get(cv::CAP_PROP_FPS);
// 创建视频写入对象
std::filesystem::create_directories(saveFolder); // 创建保存文件夹(如果不存在)
std::string savePath = saveFolder + "result.mp4";
cv::VideoWriter writer(savePath, cv::VideoWriter::fourcc('m', 'p', '4', 'v'), fps, cv::Size(frameWidth, frameHeight));
cv::Mat frame;
while (true) {
if (!cap.read(frame)) {
std::cerr << "Error: Could not read frame from camera." << std::endl;
break;
}
std::vector<DL_RESULT> res;
p->RunSession(frame, res);
for (auto& re : res) {
cv::RNG rng(cv::getTickCount());
cv::Scalar color(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
cv::rectangle(frame, re.box, color, 3);
float confidence = floor(100 * re.confidence) / 100;
std::cout << std::fixed << std::setprecision(2);
std::string label = p->classes[re.classId] + " " +
std::to_string(confidence).substr(0, std::to_string(confidence).size() - 4);
cv::rectangle(
frame,
cv::Point(re.box.x, re.box.y - 25),
cv::Point(re.box.x + label.length() * 15, re.box.y),
color,
cv::FILLED
);
cv::putText(
frame,
label,
cv::Point(re.box.x, re.box.y - 5),
cv::FONT_HERSHEY_SIMPLEX,
0.75,
cv::Scalar(0, 0, 0),
2
);
}
// 将处理后的帧写入视频文件
writer.write(frame);
// 显示处理后的帧
cv::imshow("Camera Detection", frame);
// 按 'q' 键退出循环
if (cv::waitKey(1) == 'q') {
break;
}
}
cap.release();
writer.release();
// 检查视频文件是否成功创建
if (fs::exists(savePath)) {
std::cout << "Video saved successfully to: " << savePath << std::endl;
} else {
std::cerr << "Error: Failed to save video to: " << savePath << std::endl;
}
cv::destroyAllWindows();
}
void DetectTest() {
YOLO_V8* yoloDetector = new YOLO_V8;
// ReadCocoYaml(yoloDetector);
yoloDetector->classes = { "0", "1" };
DL_INIT_PARAM params;
params.rectConfidenceThreshold = 0.1;
params.iouThreshold = 0.5;
params.modelPath = "your/weight/path/best.onnx";
params.imgSize = { 640, 640 };
#ifdef USE_CUDA
params.cudaEnable = true;
// GPU FP32 inference
params.modelType = YOLO_DETECT_V8;
// GPU FP16 inference
//Note: change fp16 onnx model
//params.modelType = YOLO_DETECT_V8_HALF;
#else
// CPU inference
params.modelType = YOLO_DETECT_V8;
params.cudaEnable = false;
#endif
yoloDetector->CreateSession(params);
std::string save_folder = "F:/opencv_cuda/vedio_detect/vedio_detect/output/";
DetectFromCamera(yoloDetector, save_folder);
}
int main() {
DetectTest();
// ClsTest();
}
笔者第一次写博客,如有冒犯,请多多包涵