OpenCV-DNN使用SSD网络目标检测-程序员宅基地

技术标签: 深度学习应用开发  opencv-dnn  ssd  目标检测  caffemodel  VOC  图像处理|OpenCV|Halcon  

开发环境

    VS2013 + OpenCV3.4.1 + Qt5.8.0

实验准备

    VGG_VOC0712_SSD_300x300_iter_120000.caffemodel

    deploy.prototxt

    以上数据可以由这里下载得到(或者直接下载本工程),使用的是基于Caffe+VOC0712数据集训练出来的caffemodel。

主要代码

读取网络

string modelTxt = "caffe_ssd_300x300/deploy.prototxt";
string modelBin = "caffe_ssd_300x300/VGG_VOC0712_SSD_300x300_iter_120000.caffemodel";
try{

	net = dnn::readNetFromCaffe(modelTxt, 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;
	}
}

前向识别

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.0f, Size(300, 300), Scalar(104, 117, 123), false, false); //Convert Mat to batch of images
net.setInput(inputBlob, "data");						//set the network input
Mat detection = net.forward("detection_out");			//compute output

ostringstream ss;
vector<double> layersTimings;
Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());

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++){

	float confidence = detectionMat.at<float>(i, 2);

	if (confidence > confidenceThreshold){

		size_t objectClass = (size_t)(detectionMat.at<float>(i, 1));
		int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols);
		int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows);
		int xRightTop	= static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols);
		int yRightTop	= static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows);
		ss.str("");
		ss << confidence;
		String conf(ss.str());
		Rect object(xLeftBottom, yLeftBottom, xRightTop - xLeftBottom, yRightTop - yLeftBottom);
		rectangle(frame, object, Scalar(0, 0, 255));
		//String label = String(classNames[objectClass]) + ": " + conf;
		String label = String(classNamesZH[objectClass]) + ": " + conf;
		
		int baseLine = 0;
		Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.48, 1, &baseLine);
		rectangle(frame, Rect(Point(xLeftBottom, yLeftBottom + labelSize.height / 2 - 4),
			Size(labelSize.width, labelSize.height + baseLine)),
			Scalar(255, 255, 255), FILLED);

		//putText(frame, label, Point(xLeftBottom, yLeftBottom), FONT_HERSHEY_SIMPLEX, 0.48, Scalar(0, 0, 0));
		putTextZH(frame, label.c_str(), Point(xLeftBottom, yLeftBottom), Scalar(0, 0, 255), 14, "Arial");
	}
}

Mat detectionMat是输入图像后经过网络前向传播后的输出7*10的结果矩阵,其定义如下图所示:


目标为20分类,定义如下:

const char* classNames[] = { "background",
"aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair",
"cow", "diningtable", "dog", "horse",
"motorbike", "person", "pottedplant",
"sheep", "sofa", "train", "tvmonitor" };

const char* classNamesZH[] = { 
"背景","飞机", "自行车", "鸟", "船",
"瓶子", "巴士", "汽车", "猫", "椅子",
"牛", "餐桌", "狗", "马","摩托车", 
"人", "盆栽","羊", "沙发", "火车", "电视" };

上图中置信概率最高(0.999)的目标数组下标为2,对应的是bicycle自行车,只要大于设置的阈值(变量confidenceThreshold),就会在图像上标记出目标的位置(detectionMat行向量的3,4,5,6元素)。比如将阈值confidenceThreshold设置为0.5,则识别结果只有一个是大于0.5的,则只会在图像上标记出自行车,如下图:


实验效果

本地图片



相机实时

在相机上(普通的USB相机)会比较卡顿···,因为用的是CPU跑的,附上本人帅照···


附件

    源代码工程戳这里(注:release下的可执行程序可以直接运行)。


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/KayChanGEEK/article/details/79978851

智能推荐

权限录入 html树,权限树.html-程序员宅基地

权限树$axure.utils.getTransparentGifPath = function() { return 'resources/images/transparent.gif'; };$axure.utils.getOtherPath = function() { return 'resources/Other.html'; };$axure.utils.getReloadPath ..._html 权限菜单树

关于避免fragment重复加载_怎么让fragment不重复show()-程序员宅基地

当一个而在存在多个fragment并要切换时,fragment 会多次重复加载,怎么解决呢,大概思路是当滑动到当前页面的时候把你要显示的show就行了.`要使用到的两个方法如下:getSupportFragmentManager().beginTransaction() .hide(promotionF).hide(promoteSpotF) .add(id.c_怎么让fragment不重复show()

ES6 深拷贝_JavaScript基础心法——深拷贝和浅拷贝-程序员宅基地

浅拷贝和深拷贝都是对于 JS 中的引用类型而言的,浅拷贝就只是复制对象的引用,如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正地对对象的拷贝。前言 说到深浅拷贝,必须先提到的是JavaScript的数据类型,之前的一篇文章JavaScript基础心法——数据类型说的很清楚了,这里就不多说了。需要知道的就是一点:JavaScript的数据类型分为基本数据类型和引用数据类型。..._es6 concat是深拷贝吗

linux中setside命令,lsmod命令_Linux lsmod 命令用法详解:显示已载入系统的模块_CharlesDDDD的博客-程序员宅基地

lsmod命令用于显示已经加载到内核中的模块的状态信息。执行lsmod命令后会列出所有已载入系统的模块。Linux操作系统的核心具有模块化的特性,应此在编译核心时,务须把全部的功能都放入核心。您可以将这些功能编译成一个个单独的模块,待需要时再分别载入。语法lsmod实例[root@LinServ-1 ~]# lsmodModule Size Used byipv..._linux主机检测使用什么命令查看已载入系统模块

结构体里面要不要定义指针-程序员宅基地

giflib里面定义了很多结构体 每个结构体对应一种描述结构体里面用了很多指针 存储GIF文件的各类数据在使用的过程中常常致使指针偏移 delete 出错。朋友建议我这样做:代码实现structitem{ints;intb;};structsss{intnCount;itemit[1];};sss*p=(sss*)malloc(si...

信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1107:校门外的树_某校大门外长度为 l的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我-程序员宅基地

时间限制: 1000 ms 内存限制: 65536 KB提交数: 11290 通过数: 6162【题目描述】某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。由于马路上有一些区域要用来建地铁。这些区域用它们在数轴..._某校大门外长度为 l的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我

随便推点

画出matlab语音信号受AWGN,信号与系统课程设计报告.doc_江小柴的博客-程序员宅基地

信号与系统课程设计报告.doc 信号与系统课程设计报告频分复用通信系统的仿真设计指导老师XXX小组成员摘要通过对信号与系统这门课程第八章通信系统学习,我们对频分复用(FDMA)技术产生了浓厚的兴趣,于是决定自己利用MATLAB强大的仿真功能来对频分复用系统进行仿真。本文首先录制三段不同的语音信号。然后通过推导,确定合适的载波信号的频率,对信号进行调制,调制后整合到一个复用信号上。再在复用信号上加一..._信号与系统课设语音信号

安卓开发快速上手!一个本科渣渣是怎么逆袭从咸鱼到Offer收割机的?分享PDF高清版_java serializable parcelelable_椰果学Android的博客-程序员宅基地

腾讯面试中的重点及经常问到技术点:数据结构算法,调优,View,SDK**,**动画音视频等以及你使用过的框架且第一轮的基础很重要,通过后录取可能性就相对高了!金三银四已经到了,在这也免费分享一些Java程序员面试常问架构面试专题和答案以及架构视频资料(文末领取),希望那些有需要朋友能在今年第一波招聘潮找到一个自己满意顺心的工作!面试大纲1.java基础、面向对象、集合、线程使用;2.Android 机型适配、SDK适配、内存优化、内存溢出、内存泄漏;3.MVC/MVP/MVVM的使用场景;4._java serializable parcelelable

MySQL 建表字段长度的限制问题-程序员宅基地

文章详细内容MySQL 建表字段长度的限制问题发布日期:2013年08月05日 来源:PHP1.CN 点击:1903摘要:用了这么久的MySQL,这个基本的建表限制都还不知道,惭愧啊...在MySQL建表时,遇到一个奇怪的现象: root@localhost : test 10:30:54>CREATE TABLE tb_test (

比较skb_clone和skb_cpoy-程序员宅基地

比较skb_clone和skb_cpoy 比较skb_clone和skb_cpoy posted on 2017-03-30 18:15 xuhaohunter 阅读(...) 评论(...) 编辑 收藏 var allowComments=true,cb_blo...

七年级信息技术计算机的基本操作教案,初一信息技术优秀教案-程序员宅基地

初一信息技术优秀教案教学目标(思想、知识、能力)1、仔细观察,说说你的计算机系统的外观组成。2、制作一张记录表格,记录下每个部件的品牌或型号。教学重、难点微机的基本结构和软件介绍教法、学法师:讲演辅结合 生:边学边练,自主探究教 学 程 序认 知操 作一、复习提问1、什么叫信息?你心目中的信息社会是怎样的`?2、什么叫信息技术?二、新知1、计算机在信息社会中的地位和作用2、微型计算机的基本结构和软...