玩转OpenCV3——DNN

在上一篇中安装好了OpenCV3.1的环境后,继续研究官方文档中关于contrib库的教程。
DNN即Deep Neural Networks,也就是深层神经网络,是目前深度学习概念中最基本的一种技术框架。
相对于传统的人工神经网络(包括多层神经网络),对DNN的关键不同点的一种解释是:其在做有监督学习前要先做非监督学习,然后将非监督学习学到的权值当作有监督学习的初值进行训练。

1. 准备工作

这次要看的教程是Load Caffe framework models。
在VS中新建一个名为caffe_googlenet的win32控制台项目,将opencv_contrib\modules\dnn\samples目录下的4个文件拷贝至项目文件夹内覆盖。
另外还差一个bvlc_googlenet.caffemodel文件需要单独下载,即训练好的分类器模型。

其中Caffe是一个深度学习框架,由Berkeley大学研究并发布。
官方教程中给出的下载链接貌似被墙了,可以到我的云盘分享去下载,提取码1d6e。

此时已经可以编译运行了。
输入的图像为:


玩转OpenCV3——DNN_第1张图片
space shuttle

得到结果如下:

Net Outputs(1):
prob
Best class: #812 'space shuttle'
Probability: 99.9799%

即输入图片属于分类space shuttle的可能性为99.9799%。

2. 代码分析

源码就不贴了,opencv_contrib\modules\dnn\samples文件夹下有现成的cpp文件。
几个关键步骤如下:
(1)载入Caffe模型

Ptr importer;
importer = dnn::createCaffeImporter(modelTxt, modelBin);   

(2)创建神经网络并初始化

dnn::Net net;
importer->populateNet(net);
importer.release();

(3)读取输入图像并转化为GoogleNet可识别的blob格式

Mat img = imread(imageFile);
resize(img, img, Size(224, 224));
dnn::Blob inputBlob = dnn::Blob(img); 

(4)将图像数据输入网络

net.setBlob(".data", inputBlob);

(5)计算输出

net.forward();

(6)取出prob层的输出,确定最终的分类

dnn::Blob prob = net.getBlob("prob");
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);

3. 进一步分析

我们来分析一下例程中提供的几个文件。

  • bvlc_googlenet.caffemodel
    刚刚已经说过,是训练好的分类器模型。

  • bvlc_googlenet.prototxt
    根据存储的内容来看应该是记录了生成的深度神经网络结构。

  • synset_words.txt
    存储了该分类模型可以识别的图像内容的种类。

我们从synset_words.txt中随机选取几个其他类别的物品来试一试。

第一张图片:


玩转OpenCV3——DNN_第2张图片
car

识别结果:

Best class: #817 'sports car, sport car'
Probability: 81.8836%

第二张图片:


玩转OpenCV3——DNN_第3张图片
shark

识别结果:

Best class: #2 'great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias'
Probability: 87.1443%

第三张图片并没有对应给出的分类,而是从新闻联播中随机拉了一张截图:


玩转OpenCV3——DNN_第4张图片
news

识别结果:

Best class: #624 'library'
Probability: 11.234%

并没有适合的分类,但至少识别出了这是一个室内的场景。

用单一分类器可以识别这么多种类的东西,效果还是挺感人的。

4. 后续

目前只是调用了已经训练好的分类器,后边会研究一下如何自己来训练所需要的分类器。
也许实现人工智能真的不再是科学幻想了,而就在即将到来的时代。

你可能感兴趣的:(玩转OpenCV3——DNN)