玩转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。

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


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<dnn::Importer> 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中随机选取几个其他类别的物品来试一试。

第一张图片:


car

识别结果:

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

第二张图片:


shark

识别结果:

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

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


news

识别结果:

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

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

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

4. 后续

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容