当前位置:   article > 正文

目标检测笔记——基于win10实现用darknet-yolov4结合opencv用C++实现实时检测_多目标检测 windows

多目标检测 windows

所需环境:
环境

win10
VS2017
opencv4.5.4
算法darkmet-yolov4
  • 1
  • 2
  • 3
  • 4

https://github.com/AlexeyAB/darknet

进入目录

.\darknet-master\darknet-master\build\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" />
  • 1

在这里插入图片描述
237行加入:

<ClInclude Include="..\..\src\representation_layer.h" />
  • 1

在这里插入图片描述
改完后,重新打开工程,编译成功,得到以下文件。
在这里插入图片描述

解决方法也可以参考下面网址:
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.dllyolo_cpp_dll.lib、pthreadGC2.dllpthreadVC2.dllyolo_v2_class.hpp放到工程目录.\yolov4test\yolov4test
在这里插入图片描述
引入yolo_cpp_dll.libyolo_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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/178112
推荐阅读
相关标签
  

闽ICP备14008679号