使用 C++ 调用 YOLOv3 模型进行物体检测

  1. 环境准备
    首先,确保你已经安装了以下工具:

OpenCV:用于图像处理。
Darknet:用于 YOLO 模型的推理。
C++ 编译器:如 g++。
2. 安装 Darknet
克隆 Darknet 仓库并进入目录:

bash

git clone https://github.com/pjreddie/darknet.git
cd darknet
使用 Makefile 编译 Darknet(如果使用 GPU 支持,记得修改 Makefile,启用 GPU 和 CUDNN):

bash

make
下载 YOLOv3 的预训练权重文件:

bash

wget https://pjreddie.com/media/files/yolov3.weights
3. 使用 C++ 进行物体检测
接下来我们编写一个简单的 C++ 程序,使用 YOLOv3 模型进行物体检测。

C++ 程序 (yolo_detect.cpp)
cpp

include

include <opencv2/opencv.hpp>

include <opencv2/dnn.hpp>

using namespace std;
using namespace cv;
using namespace cv::dnn;

// 加载 YOLO 模型文件
const String modelConfiguration = "cfg/yolov3.cfg"; // YOLO 配置文件路径
const String modelWeights = "yolov3.weights"; // YOLO 权重文件路径
const String classesFile = "cfg/coco.names"; // 类别文件,包含检测物体的类别名称

vector classNames;

// 加载类别文件
void loadClassNames(const string& filename) {
ifstream classFile(filename);
string line;
while (getline(classFile, line)) {
classNames.push_back(line);
}
}

// 加载 YOLO 模型
Net loadYOLOModel() {
// 加载 YOLO 配置文件和权重文件
Net net = readNetFromDarknet(modelConfiguration, modelWeights);
return net;
}

// 物体检测函数
void detectObjects(Mat& frame, Net& net) {
Mat blob;
// 将图像转换为 blob(神经网络的输入格式)
blobFromImage(frame, blob, 1/255.0, Size(416, 416), Scalar(), true, false);

// 将 blob 设置为网络输入
net.setInput(blob);

// 获取网络的所有输出层
vector<String> outNames = net.getUnconnectedOutLayersNames();
vector<Mat> outs;
net.forward(outs, outNames);

// 解析 YOLO 输出
for (size_t i = 0; i < outs.size(); ++i) {
    float* data = (float*)outs[i].data;
    for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols) {
        // 获取每个框的概率
        float confidence = data[4];
        if (confidence > 0.5) {
            // 计算类别
            int classID = -1;
            float maxClassProb = -1;
            for (int k = 5; k < outs[i].cols; ++k) {
                if (data[k] > maxClassProb) {
                    maxClassProb = data[k];
                    classID = k - 5;
                }
            }

            // 如果类别有效,画出矩形框
            if (classID >= 0) {
                int x = (int)(data[0] * frame.cols);
                int y = (int)(data[1] * frame.rows);
                int w = (int)(data[2] * frame.cols);
                int h = (int)(data[3] * frame.rows);

                // 绘制边界框
                rectangle(frame, Point(x, y), Point(x + w, y + h), Scalar(0, 255, 0), 2);

                // 在框上写上类别名
                putText(frame, classNames[classID], Point(x, y - 5), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 2);
            }
        }
    }
}

}

int main() {
// 加载类别名称
loadClassNames(classesFile);

// 加载 YOLO 模型
Net net = loadYOLOModel();

// 打开视频或摄像头
VideoCapture cap("test.jpg");  // 可以换成视频路径或者摄像头索引(0 为默认摄像头)
if (!cap.isOpened()) {
    cerr << "Error: Cannot open video stream or image." << endl;
    return -1;
}

// 循环读取每一帧
while (true) {
    Mat frame;
    cap >> frame;  // 读取一帧

    if (frame.empty()) {
        break;  // 如果没有帧则退出
    }

    // 检测物体
    detectObjects(frame, net);

    // 显示结果
    imshow("YOLO Object Detection", frame);

    // 按下 'q' 键退出
    if (waitKey(1) == 'q') {
        break;
    }
}

return 0;

}
4. 编译和运行
确保你已经安装了 OpenCV 和 C++ 编译器。
编译 C++ 程序:
bash更多内容访问ttocr.com或联系1436423940

g++ -o yolo_detect yolo_detect.cpp pkg-config --cflags --libs opencv4
运行程序:
bash

./yolo_detect
5. 程序说明
加载 YOLO 模型: 我们使用 cv::dnn::readNetFromDarknet 来加载 YOLOv3 的配置和权重文件。
物体检测: 在 detectObjects 函数中,我们将图像转换为模型可以接受的输入格式(blob),然后通过 net.forward() 进行推理,得到检测结果。我们从每个检测框中提取置信度,并在图像中绘制边界框。
OpenCV 显示图像: 使用 imshow 展示检测结果,按 q 键退出。
6. 结果展示
运行程序后,YOLO 模型会自动检测图像中的物体,并显示带有边界框的图像。

posted @   ttocr、com  阅读(157)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示