赞
踩
所需环境:
环境
win10
VS2017
opencv4.5.4
算法darkmet-yolov4
https://github.com/AlexeyAB/darknet
进入目录
.\darknet-master\darknet-master\build\darknet
根据是否有gpu选择相应.sln
文件打开,这里,由于我电脑上么有gpu,所以选择
打开工程 yolo_cpp_dll_no_gpu.sln
,把常规属性中的目标平台版本从8改为10,
修改opencv路径,编译。
出现以下错误:
无法解析的外部符号 make_implicit_layer
更改yolo_cpp_dll_no_gpu.vcxproj
文件
注意:
下面的2条修改,我在测试时,66行的不需要修改
,也可以正常编译成功。
163行加入:
<ClCompile Include="..\..\src\representation_layer.c" />
237行加入:
<ClInclude Include="..\..\src\representation_layer.h" />
改完后,重新打开工程,编译成功,得到以下文件。
解决方法也可以参考下面网址:
https://blog.csdn.net/weixin_50521062/article/details/121267907
注意:
我在测试时,66行的不需要修改
,也可以正常编译成功。
注意:默认yolov4
默认字符集是“多字节字符集”,根据需要可以在工程属性中改为unicode,一样可以编译通过。
如果要编译gpu版dll,必须配置好cuda合cudnn的前提下使用
参考:https://blog.csdn.net/stjuliet/article/details/87884976
https://blog.csdn.net/Angeldream123/article/details/123526012
1.修改yolo_cpp_dll.vcxproj
中CUDA的版本号,2处,打开yolo_cpp_dll.vcxproj文件,将具有CUDA
的版本改成自己使用的版本(默认为11.1
),一共有两处,分别在55行和311行:
2、特别注意要将CUDA
设备中的Generation改成自己显卡对应的计算能力(默认添加了35和75两项,可能不是你的显卡的计算能力,可以去英伟达显卡官网查询计算能力:https://developer.nvidia.com/cuda-gpus#collapseOne)
,否则接下来的生成会出错。在前面边编译训练用的工程时,也有本操作。
用VS2017新建一个工程项目yolov4test
调用dll,进入da
.\darknet-master\darknet-master\include\
.\darknet-master\darknet-master\build\darknet\x64
复制以下文件
把yolo_cpp_dll.dll
、yolo_cpp_dll.lib、pthreadGC2.dll
、pthreadVC2.dll
、yolo_v2_class.hpp
放到工程目录.\yolov4test\yolov4test
引入yolo_cpp_dll.lib
和yolo_v2_class.hpp
注意yolo_v2_class.hpp要加入
“ #define OPENCV ”`
具体使用很简单:
//创建检测器
Detector m_YoloDetector(“.cfg",".weights”);
//检测
std::vector<bbox_t> vResult = m_YoloDetector.detect(img);
经测试,debug和release都可以正常使用。
注意:
1、cfg和weights文件如果不存在,会是程序闪退,最好先判断是否存在并提示。
2、cfg和weights必须配套,也就是要用训练weights时使用的cfg,否则会检测不出结果。
3、debug和release的dll不能混用,否则会出错。
4、在调用dll的工程中的yolo_v2_class.hpp中,增加“ #define OPENCV ”
因为有一些代码是#ifdef OPENCV控制的,得加上#define OPENCV才会起作用
否则可能会有如下错误:
错误1:无法 从“cv::Mat”转换为“image_t”
错误2:无法从"cv::Mat"转换为“string",这个错误是因为错误1导致的重载函数匹配不上了。
5、gpu识别coco数据集80分类,识别一次dog.jpg的例子图像,花费3100ms。
识别自己做的1分类数据集,需要1500ms,还是很慢啊。
(cpu i7-7700HQ 2.8GHz)
相同条件下,yolov4-tiny的识别速度是yolov4的10倍,coco数据集80分类识别205ms。
6、虽然用不到,但是特殊记录一下,darknet中的图片像素点数据,都是保存的0-1之间的标准化数据。例如,darknet_R = opencv_R/255
#include <opencv2/opencv.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> #include <vector> #include <fstream> #include "yolo_v2_class.hpp" using namespace std; using namespace cv; //#define GPU //画出检测框和相关信息 void DrawBoxes(Mat &frame, vector<string> classes, int classId, float conf, int left, int top, int right, int bottom) { //画检测框 rectangle(frame, Point(left, top), Point(right, bottom), Scalar(255, 178, 50), 3); //该检测框对应的类别和置信度 string label = format("%.2f", conf); if (!classes.empty()) { CV_Assert(classId < (int)classes.size()); label = classes[classId] + ":" + label; } //将标签显示在检测框顶部 int baseLine; Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); top = max(top, labelSize.height); rectangle(frame, Point(left, top - round(1.5*labelSize.height)), Point(left + round(1.5*labelSize.width), top + baseLine), Scalar(255, 255, 255), FILLED); putText(frame, label, Point(left, top), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 0), 1); } //画出检测结果 void Drawer(Mat &frame, vector<bbox_t> outs, vector<string> classes) { //获取所有最佳检测框信息 for (int i = 0; i < outs.size(); i++) { DrawBoxes(frame, classes, outs[i].obj_id, outs[i].prob, outs[i].x, outs[i].y, outs[i].x + outs[i].w, outs[i].y + outs[i].h); } } int main(void) { string classesFile = "./yolo/coco.names"; string modelConfig = "./yolo/yolov4.cfg"; string modelWeights = "./yolo/yolov4.weights"; //加载类别名 vector<string> classes; ifstream ifs(classesFile.c_str()); string line; while (getline(ifs, line)) classes.push_back(line); //加载网络模型,0是指定第一块GPU Detector detector(modelConfig, modelWeights, 0); string mode = "video"; //图像 if (mode == "image") { Mat frame = imread("./data/test.jpg"); //Mat图像转为yolo输入格式 shared_ptr<image_t> detImg = detector.mat_to_image_resize(frame); //前向预测 vector<bbox_t> outs = detector.detect_resized(*detImg, frame.cols, frame.rows, 0.25); //画图 Drawer(frame, outs, classes); imwrite("./data/result.jpg", frame); } //视频 else if (mode == "video") { VideoCapture cap("./data/test.avi"); Size size(1920, 1080); VideoWriter writer("./data/result.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 25, size); while (1) { Mat frame; cap >> frame; if (frame.empty()) break; //Mat图像转为yolo输入格式 shared_ptr<image_t> detImg = detector.mat_to_image_resize(frame); //前向预测 vector<bbox_t> outs = detector.detect_resized(*detImg, frame.cols, frame.rows, 0.25); //画图 Drawer(frame, outs, classes); writer << frame; } cap.release(); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。