OpenCV-DNN使用YOLO网络目标检测

原创 2018年04月17日 20:34:42

开发环境

    VS2013 + OpenCV3.4.1 + Qt5.8.0

实验准备

    yolov2-tiny.cfg

    yolov2-tiny.weights

    或

    yolov2.cfg

    yolov2.weights

    或

    yolov2-voc.cfg

    yolov2-tiny-voc.weights

    以上数据的下载地址戳这里,或者直接下载我的工程(注意:由于*.weights文件过大,无法一并上传到CSDN,*.weights还是需要自行下载,*.weights下载方法如下图)

    

主要代码

加载网络和标签

string modelCfg;
string modelBin;
string classFilename;

if (idx == 0){

	modelCfg = "yolo/yolov2-tiny.cfg";
	modelBin = "yolo/yolov2-tiny.weights";
	classFilename = "yolo/darknet-master/data/coco.names";
}
if (idx == 1){

	modelCfg = "yolo/yolov2.cfg";
	modelBin = "yolo/yolov2.weights";
	classFilename = "yolo/darknet-master/data/coco.names";
}
if (idx == 2){

	modelCfg = "yolo/yolov2-voc.cfg";
	modelBin = "yolo/yolov2-tiny-voc.weights";
	classFilename = "yolo/darknet-master/data/voc.names";
}
try{

	net = dnn::readNetFromDarknet(modelCfg, modelBin);
}catch (cv::Exception &ee){

	QMessageBox::warning(this, "Exception", ee.what());
	if (net.empty()){

		QMessageBox::warning(this, "Exception", "Can't load the network by using the flowing files.");
		return;
	}
}

// Load Label
classNamesVec.clear();
ifstream classNamesFile(classFilename);
if (classNamesFile.is_open()){

	string className = "";
	while (std::getline(classNamesFile, className))
		classNamesVec.push_back(className);
}
else{

	QMessageBox::warning(this, "Exception", "Load label failed.");
	return;
}

前向识别

Mat frame;
image.copyTo(frame);
if (frame.empty()){

	QMessageBox::warning(this, "Warning", "image is empty, please check!");
	return;
}
if (frame.channels() == 4) cvtColor(frame, frame, COLOR_BGRA2BGR);

double ttt = (double)cvGetTickCount();

Mat inputBlob = blobFromImage(frame, 1 / 255.F, Size(416, 416), Scalar(), true, false); //Convert Mat to batch of images
net.setInput(inputBlob, "data");                   //set the network input]
Mat detectionMat = net.forward("detection_out");   //compute output

ttt = (double)cvGetTickCount() - ttt;
ui.labelTime->setText(toChinese("识别时间:") + QString::number(ttt / (cvGetTickFrequency() * 1000000)) + toChinese("秒"));

float confidenceThreshold = ui.dsbConfidence->value();
for (int i = 0; i < detectionMat.rows; i++){

	const int probability_index = 5;
	const int probability_size = detectionMat.cols - probability_index;
	float *prob_array_ptr = &detectionMat.at<float>(i, probability_index);

	size_t objectClass = max_element(prob_array_ptr, prob_array_ptr + probability_size) - prob_array_ptr;
	float confidence = detectionMat.at<float>(i, (int)objectClass + probability_index);

	if (confidence > confidenceThreshold){

		float x_center = detectionMat.at<float>(i, 0) * frame.cols;
		float y_center = detectionMat.at<float>(i, 1) * frame.rows;
		float width = detectionMat.at<float>(i, 2) * frame.cols;
		float height = detectionMat.at<float>(i, 3) * frame.rows;
		Point p1(cvRound(x_center - width / 2), cvRound(y_center - height / 2));
		Point p2(cvRound(x_center + width / 2), cvRound(y_center + height / 2));
		Rect object(p1, p2);

		Scalar object_roi_color(0, 255, 0);

		if (1)//
		{
			rectangle(frame, object, object_roi_color);
		}
		else
		{
			Point p_center(cvRound(x_center), cvRound(y_center));
			line(frame, object.tl(), p_center, object_roi_color, 1);
		}

		String className = objectClass < classNamesVec.size() ? classNamesVec[objectClass] : cv::format("unknown(%d)", objectClass);
		String label = format("%s: %.2f", className.c_str(), confidence);
		int baseLine = 0;
		Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
		rectangle(frame, Rect(p1, Size(labelSize.width, labelSize.height + baseLine)), object_roi_color, FILLED);
		putText(frame, label, p1 + Point(0, labelSize.height), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0));
	}
}
Mat detectionMat是一个输入图像后经过网络前向传播后的输出85*845的结果矩阵,其定义如下图所示:


行向量解析:前面4个元素是用来标记目标在图像上的位置的(被归一化了),第5个元素是置信概率,值域为[0-1](用来与阈值作比较决定是否标记目标),后面80个为基于COCO数据集的80分类的标记权重,最大的为输出分类。

列向量解析:为什么是845个?因为YOLO会把图像分成13*13的网格,每个网格预测5个BOX(所以就是13*13*5=845)。每个BOX就是一个行向量(详细的网络细节参考这里)。

实验效果

本地图片


和SSD网络对比


同等条件下和SSD网络比较,识别速度会更快。

附件

    源代码工程戳这里(注:release下的可执行程序可以直接运行,但是要先下载对应的*.weights文件,因为*.weights文件太大,无法一并上传)。


版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/KayChanGEEK/article/details/79979825

UML参考手册 第一部分 背景知识 第1章 UML 综述

 ML参考手册  第一部分 背景知识  这一部分介绍了UML的基本原理,包括UML建模的性质和目标以及UML覆盖的所有功能领域。 第1章 UML 综述  本章是UML及其应用的一个快速浏览。1.1 U...
  • CandyCat
  • CandyCat
  • 2001-05-26 22:51:00
  • 1453

opencv -dnn人脸识别(2016-10-27)

转自:http://blog.csdn.net/shakevincent/article/details/52946499 版权声明:本文为博主原创文章,未经博主允许不得转载。 ...
  • foreyang00
  • foreyang00
  • 2017-05-03 18:38:05
  • 432

OpenCV 3.3增加新模块caffe dnn

http://docs.opencv.org/master/d5/de7/tutorial_dnn_googlenet.html Load Caffe framework models ...
  • forest_world
  • forest_world
  • 2017-08-08 11:08:41
  • 1104

Opencv如何使用dnn读取caffemodel进行识别

Opencv中的dnn模块opencv3.0已经集成了基本的dnn模块,包含了通用的层。记录第一次使用情况如下:/**M////////////////////////////////////////...
  • Iriving_shu
  • Iriving_shu
  • 2017-09-29 11:40:28
  • 338

OpenCV 图像处理(直方图均衡化、拉普拉斯算子图像增强、Gamma校正)

本文主要通过OpenCV实现一些基础的图像处理过程,包括直方图均衡化、拉普拉斯算子图像增强、Gamma校正过程。 图像的对比度:灰度的动态范围来衡量。 一、直方图均衡化 直方图均衡化是通过调整图像的灰...
  • sinat_28296297
  • sinat_28296297
  • 2017-09-13 22:28:06
  • 997

新 OpenCV 多幅图像 同一个窗口 显示 代码优化版

为了能更好地、更灵活地在OpenCV中实现,同一窗口内显示多幅图像,尝试了Yang Xian 提供的代码: http://blog.csdn.net/yang_xian521/article/deta...
  • yangyangyang20092010
  • yangyangyang20092010
  • 2014-03-21 20:07:58
  • 7109

OpenCV学习笔记之CXCORE篇

为使得OpenCV的整个库便于管理和扩充,将整个库分成若干子库,CxCore是最重要的一个子库,从“core"名字可以看出,该库提供了所有OpenCV运行时的一些最基本的数据结构,包括矩阵,数组的基本...
  • sz76211822
  • sz76211822
  • 2015-08-04 15:58:37
  • 1028

OpenCV | 基本操作API

#MAT cons cv::Mat img; cv::Mat img1(1000, 1000, CV_8UC3, cv::Scalar(0, 100, 255));//cv::Scalar(里面是通道...
  • denisyq
  • denisyq
  • 2016-07-23 16:17:19
  • 1366

OpenCv 人脸检测的学习

最近公司要组织开发分享,但是自己还是新手真的不知道分享啥了,然后看了看前段时间研究过OpenCv,那么就分享他把。 openCv就不介绍了,说下人脸检测,其实是通过openCv里边已经训练好的xml文...
  • u012808234
  • u012808234
  • 2016-01-22 17:06:38
  • 2713

图像处理-形态学操作

关于形态学的实验需要对二值图像进行减噪处理,图像形态学中的腐蚀和膨胀能很好的解决此问题。如果在腐蚀和膨胀操作前,对灰度图像做一次滤波,减噪效果将更明显。 腐蚀的具体操作是:用一个结构元素(一般是3×...
  • zhangfuliang123
  • zhangfuliang123
  • 2017-05-03 17:10:30
  • 1688
收藏助手
不良信息举报
您举报文章:OpenCV-DNN使用YOLO网络目标检测
举报原因:
原因补充:

(最多只允许输入30个字)