所需环境:
环境
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
经测试,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;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)