win10 编译 YOLO v3 并通过OpenCV调用dll实时检测


安装依赖

配置

  • cuda10.1version
  • cudnn-10.1-windows10-x64-v7.5.0.56
  • Opencv3.4

安装CUDA

安装opencv

进入官网直接下载, 提取并安装 https://opencv.org/opencv-3-4.html
注意将dll所在的目录D:\opencv\build\x64\vc15\bin添加到环境变量.

安装VS2017

安装社区版, 成功后, 将CUDA的扩展文件复制到VS目录.
注: 可以先在VS中编译DarkNet, 根据错误信息, 确定具体目录. 我这里是从下图
在这里插入图片描述
复制到这里 C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\BuildCustomizations

编译

exe

  • 下载工程 https://github.com/AlexeyAB/darknet
  • 下载预训练权重 https://pjreddie.com/media/files/yolov3.weights
  • 打开 .\darknet-master\build\darknet目录, 进入.\darknet-master\build\darknet中, 没有GPU的打开darknet_no_gpu.sln,有GPU的打开 darknet.sln.
  • 将项目修改为Release x64
  • 右键项目-->重定向项目. 升不升级无所谓.
  • 包含目录,库目录, 链接器分别添加opencv的对应项
  • 其他dll只要配置好环境变量, 就不用复制到exe文件夹, 全局都可以运行
  • 右键解决方案, 重新生成即可

dll

将项目换成 yolo_cpp_dll.sln, 按上述步骤重新生成即可.

测试运行exe

  • yolov3.weights放到 .\darknet-master\build\darknet\x64目录
  • 双击darknet_yolo_v3.cmd, 出现下图所示即运行成功.
    在这里插入图片描述
  • 调用摄像头测试 , 还是在x64目录下, cmd执行命令如下:
darknet.exe detector demo data\coco.data yolov3.cfg yolov3.weights

在这里插入图片描述
其他请参考 https://blog.csdn.net/KID_yuan/article/details/88380269

OpenCV调用动态链接库dll

整个项目已经上传 点击下载 , 只需要更改opencv的属性表配置即可release运行

  • 按上述步骤, 完成编译生成dll
  • 将调用所需的所有文件找出来放在一起:
    • 1、动态链接库(.\darknet-master\build\darknet\x64
      • yolo_cpp_dll.lib
      • yolo_cpp_dll.dll
      • pthreadGC2.dll
      • pthreadVC2.dll
    • 2、OpenCV库
      • opencv_world340.dll
    • 3、YOLO模型文件(第一个文件在目录下,第二个文件在目录下,第三个文件需要自己下载,下载链接见前一篇文章)
      • coco.names .\darknet-master\build\darknet\x64\data
      • yolov3.cfg .\darknet-master\build\darknet\x64
      • yolov3.weights 下载链接: https://pjreddie.com/media/files/yolov3.weights
    • 4、头文件
      • yolo_v2_class.hpp .\darknet-master\include
  • 建议将上述文件的路径添加到环境变量中, 尤其是dll类
  • 新建opencv项目, 添加包含目录/库目录/链接器输入项, 代码如下.
#include <iostream>

#define OPENCV      // 启用opencv
#define GPU         // 启用GPU

#include "yolo_v2_class.hpp"
#include <opencv2/opencv.hpp>	

void draw_boxes(cv::Mat mat_img, std::vector<bbox_t> result_vec, std::vector<std::string> obj_names,
                int current_det_fps = -1, int current_cap_fps = -1)
{
    int const colors[6][3] = { { 1,0,1 },{ 0,0,1 },{ 0,1,1 },{ 0,1,0 },{ 1,1,0 },{ 1,0,0 } };
    for (auto &i : result_vec) 
    {
        cv::Scalar color = obj_id_to_color(i.obj_id);
        cv::rectangle(mat_img, cv::Rect(i.x, i.y, i.w, i.h), color, 2);
        if (obj_names.size() > i.obj_id) 
        {
            std::string obj_name = obj_names[i.obj_id];
            if (i.track_id > 0) obj_name += " - " + std::to_string(i.track_id);
            cv::Size const text_size = getTextSize(obj_name, cv::FONT_HERSHEY_COMPLEX_SMALL, 1.2, 2, 0);
            int const max_width = (text_size.width > i.w + 2) ? text_size.width : (i.w + 2);
            cv::rectangle(mat_img, cv::Point2f(std::max((int)i.x - 1, 0), std::max((int)i.y - 30, 0)),
                          cv::Point2f(std::min((int)i.x + max_width, mat_img.cols - 1), std::min((int)i.y, mat_img.rows - 1)),
                          color, CV_FILLED, 8, 0);
            putText(mat_img, obj_name, cv::Point2f(i.x, i.y - 10), cv::FONT_HERSHEY_COMPLEX_SMALL, 1.2, cv::Scalar(0, 0, 0), 2);
        }
    }
}

std::vector<std::string> objects_names_from_file(std::string const filename) 
{
    std::ifstream file(filename);
    std::vector<std::string> file_lines;
    if (!file.is_open()) return file_lines;
    for (std::string line; getline(file, line);) file_lines.push_back(line);
    std::cout << "object names loaded \n";
    return file_lines;
}

int main()
{
    std::string  names_file = "../params/coco.names";
    std::string  cfg_file = "../params/yolov3.cfg";
    std::string  weights_file = "../params/yolov3.weights";
    Detector detector(cfg_file, weights_file);//初始化检测器
    auto obj_names = objects_names_from_file(names_file);//获得分类对象名称

    // 打开默认摄像头
    cv::VideoCapture capture;
    capture.open(0);
    if (!capture.isOpened())
    {
        printf("摄像头打开失败");
        return -1;
    }

    // 实时检测
    cv::Mat frame;
    while(true)
    {
        capture >> frame;
        std::vector<bbox_t> result_vec = detector.detect(frame);
        draw_boxes(frame, result_vec, obj_names);
        cv::imshow("YOLO v3 Camera", frame);
        if (cv::waitKey(1) == 27) break;  // ESC键退出
    }
    cv::destroyAllWindows();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Augurlee/article/details/103530487