文章目录
前言
上一篇文章: 链接主要写如何生成一个动态库,但是没有具体讲解怎么在一个新的项目中,从0开始配置一个项目,并且调用动态库Dll.
这里面动态库dll文件和lib文件都是从上一篇文章生成的,具体可以看看之前几篇文章。本篇文章主要写关于如何调用动态库,读取图片,输入检测,输出保存结果。
注意点:这个如果输入batch,每一张图片的尺寸必须要一样的,因为在图片初始化,和后处理返回坐标时候,是根据第一张图片的原始尺寸进行处理的。
在计算机视觉领域,YOLO系列模型以其高效的目标检测性能被广泛应用。本文将详细介绍如何基于已封装的YOLOv8 DLL库,搭建C++项目并实现目标检测功能,包括项目创建、环境配置、代码部署及调试运行全流程。

1. 新建一个C++空项目
首先我们需要在Visual Studio中创建一个C++空项目,作为调用YOLOv8 DLL库的载体:
- 打开Visual Studio(以VS2019/2022为例),点击「创建新项目」;
- 在项目模板中搜索「空项目」,选择「C++ 空项目」,点击「下一步」;
- 设置项目名称(如
CallYolov8DllProject)和存储路径,点击「创建」; - 创建完成后,在解决方案资源管理器中会看到一个空的项目结构。

2. 添加配置(属性管理器)
YOLOv8的运行依赖CUDA、TensorRT和OpenCV等库,需要通过属性管理器配置相关环境。具体步骤如下:
-
打开属性管理器:在VS菜单栏中选择「视图」->「其他窗口」->「属性管理器」;
-
右键点击项目名称(如
CallYolov8DllProject)下的「Debug|x64」(或Release|x64,根据需求选择),选择「添加现有属性表」; -
分别添加CUDA、TensorRT和OpenCV对应的属性表(
.props文件)。属性表的具体配置方法可参考文章:《TensorRT+CUDA+OpenCV环境配置教程》(包含库目录、包含目录、链接器等关键配置);

-
配置完成后,确保平台选择为「x64」(YOLOv8 DLL通常基于64位环境编译)。
查看之前写的文章,第四个章节配置部分,这边不再重复。
参考文章:YOLOv8 在 Windows 环境下基于 VS C++ 项目部署 TensorRT 模型教程

3. 添加头文件
YOLOv8 DLL库的接口定义在头文件中,需将头文件添加到项目中以便调用:
- 将提供的
yolov8_interface_b.h头文件复制到项目的源文件目录(与.cpp文件同目录,或单独创建include文件夹存放); - 在VS解决方案资源管理器中,右键点击「头文件」->「添加」->「现有项」;
- 选择复制好的
yolov8_interface_b.h,点击「添加」,完成头文件导入。
头文件中定义了检测框结构体Box_m和核心接口(初始化、检测、释放资源),是调用DLL的关键。

4. 添加库文件
为了让项目能够链接到YOLOv8 DLL库,需要配置库文件:
- 将生成的YOLOv8 DLL库文件(
.dll和.lib)复制到项目的输出目录(通常为x64/Debug或x64/Release,与可执行文件同目录); - 在VS中配置lib文件:右键点击项目->「属性」->「链接器」->「输入」->「附加依赖项」,点击右侧下拉框选择「编辑」;
- 在弹出的对话框中输入YOLOv8库对应的
.lib文件名(如yolov8_lib.lib,具体名称以实际生成的库为准),点击「确定」; - 确保
.dll文件在程序运行时可被找到(放置在输出目录或系统PATH路径中)。
.

5. 调试运行
配置完成后,即可编译并调试项目:
- 检查项目设置:确认「配置」为Debug(或Release),「平台」为x64;
- 准备测试图片:将测试图片(如
bus.jpg)复制到项目的工作目录(默认为项目根目录,可在「属性」->「调试」->「工作目录」中修改); - 编译项目:点击「生成」->「生成解决方案」,确保无编译错误;
- 运行程序:点击「调试」->「开始执行(不调试)」,程序会加载图片并进行目标检测,最终生成带检测框的结果图片(如
result_0.jpg); - 若运行失败,检查依赖库是否齐全(如OpenCV的
opencv_worldxxx.dll、TensorRT的nvinfer.dll等是否在路径中),或模型路径是否正确。

6. 完整Demo代码
以下是调用YOLOv8 DLL库的完整示例代码(main_b.cpp):
#include <iostream>
#include <opencv2/opencv.hpp>
#include "yolov8_interface_b.h" // 假设已修改为批量接口的头文件
int main() {
// 加载多张测试图像(示例加载3张,可根据需求增减)
std::vector<cv::Mat> images;
images.push_back(cv::imread("zidane.jpg"));
images.push_back(cv::imread("zidane.jpg")); // 假设存在的第二张图
images.push_back(cv::imread("zidane.jpg")); // 假设存在的第三张图
// 检查图片加载情况
for (size_t i = 0; i < images.size(); ++i) {
if (images[i].empty()) {
std::cerr << "Failed to load image at index " << i << std::endl;
return -1;
}
}
// COCO80类别名称(保持不变)
std::vector<std::string> coco80 = {
"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"
};
// 初始化参数(注意batchSize应与实际处理的批量大小一致)
int numClass = 80;
int batchSize = images.size(); // 批量大小设为输入图片数量
int dstH = 640;
int dstW = 640;
float confThresh = 0.25f;
float iouThresh = 0.45f;
void* yoloPtr = nullptr;
// 取第一张图的尺寸作为源图尺寸(如果所有图尺寸一致)
// 若图片尺寸不一致,建议先统一预处理或修改接口支持动态尺寸
int imageWidth = images[0].cols;
int imageHeight = images[0].rows;
char* model_path = (char*)"E:\\download\\env_download_package\\TensorRT-8.5.3.1\\bin\\yolov8n.trt";
// 初始化YOLOV8模型(批量模式)
if (initialize(model_path, numClass, batchSize, imageWidth, imageHeight, dstH, dstW, confThresh, iouThresh, &yoloPtr) != 0) {
std::cerr << "Failed to initialize YOLOV8 model." << std::endl;
release(yoloPtr);
return -1;
}
std::cout << "Initialized YOLOV8 model with parameters:" << std::endl;
std::cout << "Number of Classes: " << numClass << std::endl;
std::cout << "Batch Size: " << batchSize << std::endl;
std::cout << "Destination Height: " << dstH << std::endl;
std::cout << "Destination Width: " << dstW << std::endl;
std::cout << "Confidence Threshold: " << confThresh << std::endl;
std::cout << "IOU Threshold: " << iouThresh << std::endl;
// 批量检测图像
std::vector<std::vector<Box_m>> batchDetections; // 二维向量:[图片索引][检测框]
if (detect(yoloPtr, images, &batchDetections) != 0) { // 传入图片向量
std::cerr << "Batch detection failed." << std::endl;
release(yoloPtr);
return -1;
}
// 处理每张图片的检测结果并保存
for (size_t imgIdx = 0; imgIdx < images.size(); ++imgIdx) {
if (imgIdx >= batchDetections.size()) {
std::cerr << "No detection results for image " << imgIdx << std::endl;
continue;
}
cv::Mat resultImg = images[imgIdx].clone(); // 复制原图用于绘制
const auto& detections = batchDetections[imgIdx]; // 当前图片的检测框
// 绘制检测框和标签
for (const auto& box : detections) {
// 绘制矩形框
cv::rectangle(resultImg,
cv::Point(box.left, box.top),
cv::Point(box.right, box.bottom),
cv::Scalar(65, 172, 90), 2, cv::LINE_AA);
// 绘制标签文本
std::string detInfo = coco80[box.label] + " " + cv::format("%.4f", box.confidence);
cv::putText(resultImg, detInfo,
cv::Point(box.left, box.top - 5),
cv::FONT_HERSHEY_DUPLEX, 0.6,
cv::Scalar(255, 255, 255), 1, cv::LINE_AA);
}
// 保存结果图(命名格式:result_0.jpg, result_1.jpg...)
std::string savePath = "result_" + std::to_string(imgIdx) + ".jpg";
if (!cv::imwrite(savePath, resultImg)) {
std::cerr << "Failed to save result image: " << savePath << std::endl;
}
else {
std::cout << "Saved result to: " << savePath << std::endl;
}
}
std::cout << "Batch detection completed successfully." << std::endl;
// 释放模型资源
release(yoloPtr);
return 0;
}
7. 代码详细注释
核心接口说明(来自yolov8_interface_b.h)
initialize:初始化YOLOv8模型,参数包括模型路径、类别数、批量大小、输入/输出尺寸、置信度阈值等,返回模型指针;detect:执行目标检测,输入图片列表和模型指针,输出检测结果(检测框列表);release:释放模型占用的资源,避免内存泄漏。
关键代码解析
- 图片加载:通过OpenCV的
imread加载图片,存储到vector<cv::Mat>中实现批量输入; - 模型初始化:调用
initialize函数,传入模型路径和检测参数,获取模型指针yoloPtr; - 批量检测:调用
detect函数,传入图片列表和模型指针,检测结果存储在batchDetections中; - 结果绘制:遍历检测结果,用
cv::rectangle绘制边界框,cv::putText添加类别和置信度标签; - 资源释放:检测完成后调用
release释放模型资源,确保程序退出时无内存泄漏。
通过以上步骤,即可快速搭建YOLOv8 DLL库的调用环境并实现目标检测功能。若遇到问题,可检查环境配置是否正确或模型路径是否有效。

1411

被折叠的 条评论
为什么被折叠?



