首先我们要搞明白图像分类和对象检测的区别:
1、图像分类:

图像分类就是将这幅图像归为某一类,图像中的对象尽量要单一。
2、对象检测:

对象检测就是将不同的对象用框圈出来并规定为某一类,对象可以多个。
首先需要下载SSD模型,可以去github上下载,也可以使用自己训练的模型,这里我使用官网训练的caffe模型。


一个是二进制模型文件,一个是描述文件。这两个文件可以在这里下载:https://download.csdn.net/download/daker_huang/10960936
我们来看看描述文件,它的开头是这样的:

可以看到,该模型所需要的图像文件的维度是3通道,300*300的大小,所以我们先来定义一下宽高:

const size_t width = 300;
const size_t height = 300;//定义图像文件宽高

从上面的文件中我们可以知道ssd模型接受的图像文件是3通道的,这里需要将图像通道数转成3通道的:

Mat frame;
src.copyTo(frame);
if (frame.channels() == 4){cvtColor(frame, frame, COLOR_BGRA2BGR);//将4通道转为3通道}if (frame.channels() == 1){cvtColor(frame, frame,COLOR_GRAY2BGR );//将单通道转为3通道}

在OpenCv-C++ -深度神经网络(DNN)模块-使用goolenet模型实现图像分类中读caffe模型使用的是dnn模块中的"readNet",在这篇文章中,依旧使用dnn模块中的"readNet"读取caffe模型。

string deploy_file = "D:/test/ssd/deploy.prototxt";  //读取描述文件
string model_file = "D:/test/ssd/VGG_VOC0712Plus_SSD_300x300_iter_240000.caffemodel";//模型文件
......
Net net = readNetFromCaffe(deploy_file, model_file);

图片中检测输出的结果需要标注,而我们有标签文件,在一开始就已经导入:

这里放上标签文件:

0,0,background
5,1,aeroplane
2,2,bicycle
15,3,bird
9,4,boat
40,5,bottle
6,6,bus
3,7,car
16,8,cat
57,9,chair
20,10,cow
61,11,diningtable
17,12,dog
18,13,horse
4,14,motorbike
1,15,person
59,16,pottedplant
19,17,sheep
58,18,sofa
7,19,train
63,20,tvmonitor

这里总共21种分类物体,不多,其实我们可以把每行英文名称前面的两个数字去掉,但是如果比较多就行不通了。这里我们用定义一个函数读取每行的英文名称:

vector<String> labels(){vector<String>objNames;ifstream fp(label_file);//打开输入流,读入文件if (!fp.is_open()){printf("文件读入失败!!!\n");exit(-1);//直接退出}string name;//标签文件中都有对应的名字while (!fp.eof())//当文件没有读到结尾{getline(fp, name);//读取每一行if (name.length()){string temp1 = name.substr(name.find(",") + 1);   //找到每行第一个逗号,从逗号后面开始取数据string temp2 = temp1.substr(temp1.find(",") + 1);//找到新的(第二个)逗号,从逗号后面开始取数据objNames.push_back(temp2);}}/*for (vector<string>::iterator iter = objNames.begin(); iter != objNames.end(); ++iter){//输出*iter才是输出那些字符串cout << *iter << endl;}*/return objNames;
}

对象检测并画框:

float confidence_threshold = 0.2;for (int i = 0; i < detectionMat.rows; i++){float confidence = detectionMat.at<float>(i, 2);    //置信度if (confidence > confidence_threshold) {size_t objIndex = (size_t)(detectionMat.at<float>(i, 1));  //标签文件的索引号float tl_x = detectionMat.at<float>(i, 3) * frame.cols;  //矩形框左上横坐标点float tl_y = detectionMat.at<float>(i, 4) * frame.rows;  //矩形框左上纵坐标点float br_x = detectionMat.at<float>(i, 5) * frame.cols;  //矩形框右下横坐标点float br_y = detectionMat.at<float>(i, 6) * frame.rows;  //矩形框右下纵坐标点Rect object_box((int)tl_x, (int)tl_y, (int)(br_x - tl_x), (int)(br_y - tl_y));rectangle(frame, object_box, Scalar(0, 0, 255), 2, 8, 0);putText(frame, format("%s", objnames[objIndex].c_str()), Point(tl_x+1, tl_y+1),FONT_HERSHEY_PLAIN, 2.0, Scalar(255, 0, 0), 2);// cout << objIndex << endl;

完整代码:

#include<opencv2/opencv.hpp>
#include<opencv2/dnn.hpp>
#include<iostream>using namespace cv;
using namespace std;
using namespace cv::dnn;const size_t width = 300;
const size_t height = 300;//定义图像文件宽高vector<String> labels();string label_file = "D:/test/ssd/labelmap.txt";
string deploy_file = "D:/test/ssd/deploy.prototxt";
string model_file = "D:/test/ssd/VGG_VOC0712Plus_SSD_300x300_iter_240000.caffemodel";int main(int argc, char **argv)
{Mat src = imread("D:/test/dnn_ssd.jpeg.jpg");if (src.empty()){cout << "图像未找到!!!" << endl; return -1;}vector<String>  objnames = labels();namedWindow("input image", WINDOW_AUTOSIZE);imshow("input image",src);Net net = readNetFromCaffe(deploy_file, model_file);Mat frame;src.copyTo(frame);if (frame.channels() == 4){cvtColor(frame, frame, COLOR_BGRA2BGR);//将4通道转为3通道}if (frame.channels() == 1){cvtColor(frame, frame,COLOR_GRAY2BGR );//将单通道转为3通道}Mat blob_Img = blobFromImage(frame, 1.0f, Size(width, height), Scalar(104, 117, 123), false, false);net.setInput(blob_Img, "data");//开始层Mat detection=net.forward("detection_out");//最后一层Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());/*detection.size[2]表示宽度detection.size[3]表示高度*/float confidence_threshold = 0.2;for (int i = 0; i < detectionMat.rows; i++){float confidence = detectionMat.at<float>(i, 2);    //置信度if (confidence > confidence_threshold) {size_t objIndex = (size_t)(detectionMat.at<float>(i, 1));  //标签文件的索引号float tl_x = detectionMat.at<float>(i, 3) * frame.cols;  //矩形框左上横坐标点float tl_y = detectionMat.at<float>(i, 4) * frame.rows;  //矩形框左上纵坐标点float br_x = detectionMat.at<float>(i, 5) * frame.cols;  //矩形框右下横坐标点float br_y = detectionMat.at<float>(i, 6) * frame.rows;  //矩形框右下纵坐标点Rect object_box((int)tl_x, (int)tl_y, (int)(br_x - tl_x), (int)(br_y - tl_y));rectangle(frame, object_box, Scalar(0, 0, 255), 2, 8, 0);putText(frame, format("%s", objnames[objIndex].c_str()), Point(tl_x+1, tl_y+1),FONT_HERSHEY_PLAIN, 2.0, Scalar(255, 0, 0), 2);//cout << objIndex << endl;}}imshow("output image", frame);waitKey(0);return 0;}vector<String> labels(){vector<String>objNames;ifstream fp(label_file);//打开输入流,读入文件if (!fp.is_open()){printf("文件读入失败!!!\n");exit(-1);//直接退出}string name;//标签文件中都有对应的名字while (!fp.eof())//当文件没有读到结尾{getline(fp, name);//读取每一行if (name.length()){string temp1 = name.substr(name.find(",") + 1);   //找到每行第一个逗号,从逗号后面开始取数据string temp2 = temp1.substr(temp1.find(",") + 1);//找到新的(第二个)逗号,从逗号后面开始取数据objNames.push_back(temp2);}}/*for (vector<string>::iterator iter = objNames.begin(); iter != objNames.end(); ++iter){//输出*iter才是输出那些字符串cout << *iter << endl;}*/return objNames;
}

运行结果:

OpenCv-C++-深度神经网络(DNN)模块-使用SSD模型实现对象检测相关推荐

  1. [OPENCV]010.深度神经网络(dnn模块)

    1.加载Caffe框架模型 在本教程中,您将学习如何使用opencv_dnn模块进行图像分类,通过使用GoogLeNet训练网络从Caffe模型动物园. 1.1.下载opencv_extra 项目 到 ...

  2. dnn神经网络_OpenCV3.3深度神经网络(DNN)模块

    今天,甜菇凉整理了一下电脑里面OpenCV深度神经网络(DNN)模块-应用视频教程,这个是贾志刚老师的视频,学习视觉的同学应该都知道贾志刚老师吧,他的视频很适合想要入门计算机视觉图像处理的小白学习,那 ...

  3. 贾志刚OpenCV3.3深度神经网络DNN模块应用学习笔记

    OpenCV3.3深度神经网络DNN模块应用全套视频.课程配套PPT的PDF版本和配套源码 全套例程源码.用到的模型文件.图片和视频素材整理 在线观看 实例1:读取单张PNG文件(opencv3.3环 ...

  4. 使用opencv dnn 模块调用darknet模型时候出错,不支持relu激活函数

    问题: 使用opencv dnn 模块调用darknet模型时候出错,报错信息为 不支持relu激活函数 以下过程为笔者自己解决该问题的过程,供各位参考学些,因为中间又遇到新的坑,所以各位务必看完再决 ...

  5. 深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用

    http://www.csdn.net/article/2014-07-11/2820628-DNN 深度神经网络(Deep Neural Networks, 简称DNN)是近年来机器学习领域中的研究 ...

  6. TensorFlow2.0(四)--Keras构建深度神经网络(DNN)

    Keras构建深度神经网络(DNN) 1. 深度神经网络简介 2. Kerase搭建DNN模型 2.1 导入相应的库 2.2 数据加载与归一化 2.3 网络模型的构建 2.4 批归一化,dropout ...

  7. 讯飞输入法将深度神经网络DNN技术应用于语音识别达到业界领先水平

    10月20日,以"语见更好的我们"为主题的"讯飞输入法10周年 A.I.输入沙龙"在北京举办.记者从活动现场了解到,自2010年10月上线至今,讯飞输入法的日语 ...

  8. 理解深度神经网络——DNN(Deep Neural Networks)

    深度神经网络--DNN 是深度学习的基础. 要理解DNN最好先搞清楚它的模型.本篇博文主要对DNN的模型与前向传播算法做一个易于理解的总结. 1.从感知机到神经网络的理解. 感知机是这么一种模型:一个 ...

  9. 多层感知器及常见激活函数-深度神经网络DNN及计算推导

    多层感知器 在之前的博客中,我们了解到,感知器(指单层感知器)具有一定的局限--无法解决异或问题,即线性不可分的问题. 将多个单层感知器进行组合,就可以得到一个多层感知器(MLP--Multi-Lay ...

最新文章

  1. 如何用c语言将度分秒变为弧度_弧度与角度从哪里来
  2. RESTful之过滤Filtering
  3. 第四章 .net core做一个简单的登录
  4. Windows Phone 开发起步之旅之二 C#中的值类型和引用类型
  5. Adaboost 算法的原理与推导(转载)
  6. php 弹出变量,php取变量出现Notice: Undefined variable 的解决方法
  7. Homebrew OS X 不可或缺的套件管理器
  8. IXMLDOMDocument 成員
  9. Android tv开发px,【Android】TV端项目开发挖坑总结
  10. poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)
  11. java继承 值_java继承
  12. Element-UI学习笔记-安装
  13. dpdk-pktgen快速发包工具踩坑日记
  14. 如何选择最合适的服务器?服务器配置方案
  15. Circos从入门到精通
  16. RGB 和 CYMK 的区别
  17. 2015多校第9场 HDU 5405 Sometimes Naive 树链剖分
  18. K3ERP web登录问题解决
  19. 运维(21) 制作WinPE启动U盘
  20. 微信小程序input框只能输入小数/正整数

热门文章

  1. webassmbly blazor实现多页签效果
  2. mac os x使用Git简易入门教程
  3. 正确的-配置Tomcat环境变量
  4. 特殊符号(一)—反斜杠 ” \ “(旋转光标和倒计时的实现)
  5. python爬虫遇到验证码、输入验证码后提醒验证码错误_爬虫遇到头疼的验证码?Python实战讲解弹窗处理和验证码识别...
  6. 基于python的情感分析案例-python snownlp情感分析简易demo(分享)
  7. php获取网卡网速,Golang 获取网卡时时带宽,可用于测速
  8. 双差法(HYPODD)定位软件安装教程2
  9. Redis的内存碎片
  10. IDM一直弹出下载框怎么办?