OpenCV3.3深度学习模块(DNN)应用-图像分类
时间:2022-05-07
本文章向大家介绍OpenCV3.3深度学习模块(DNN)应用-图像分类,主要内容包括DNN模块介绍、一:GoogleNet Caffe模型数据说明、二:编程实现、三:效果显示、四:完全的源代码、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
DNN模块介绍
在OpenCV3.3版本发布中把DNN模块从扩展模块移到了OpenCV正式发布模块中,当前DNN模块最早来自Tiny-dnn,可以加载预先训练好的Caffe模型数据,OpenCV做了近一步扩展支持所有主流的深度学习框架训练生成与导出模型数据加载,常见的有如下:
- Caffe
- TensorFlow
- Torch/PyTorch
OpenCV中DNN模块已经支持与测试过这些常见的网络模块
- AlexNet
- GoogLeNet v1 (also referred to as Inception-5h)
- ResNet-34/50/...
- SqueezeNet v1.1
- VGG-based FCN (semantical segmentation network)
- ENet (lightweight semantical segmentation network)
- VGG-based SSD (object detection network)
- MobileNet-based SSD (light-weight object detection network)
一:GoogleNet Caffe模型数据说明
OpenCV通过支持加载这些预先训练好的模型,实现图像分类、对象检测、语义分割、风格迁移等功能。支持Android/iOS等移动端平台开发。下面我们就以OpenCV3.3 使用Caffe的GoogleNet数据模型为例,实现对图像常见分类,OpenCV3.3的DNN模块使用的模型支持1000种常见图像分类、googlenet深度学习网络模型是2014图像分类比赛的冠军、首先是下载相关的数据模型文件
- bvlc_googlenet.caffemodel
- bvlc_googlenet.prototxt
其中prototxt是一个文本的JSON文件、一看就明白啦,另外一个文件二进制文件。文本文件只有你下载了OpenCV3.3解压缩之后就会在对应的目录发现。模型文件需要从以下地址下载即可: http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel
二:编程实现
首先我们需要加载它官方指定的一张测试图像space_shuttle.jpg 是一张航天飞机的图片、OpenCV中加载图像的代码如下:
Mat testImage = imread("D:/vcprojects/images/dnn/football.jpg");
if (testImage.empty()) {
printf("could not load image...n");
return -1;
}
然后我们需要声明模型数据的路径与标记数据路径,加载创建网络模型,代码实现如下:
// create googlenet with caffemodel text and bin
Net net = dnn::readNetFromCaffe(modelTxt, modelBin);
if (net.empty())
{
std::cerr << "Can't load network by using the following files: " << std::endl;
std::cerr << "prototxt: " << modelTxt << std::endl;
std::cerr << "caffemodel: " << modelBin << std::endl;
return -1;
}
// 读取分类数据
vector<String> labels = readClasslabels();
//GoogLeNet accepts only 224x224 RGB-images
Mat inputBlob = blobFromImage(testImage, 1, Size(224, 224), Scalar(104, 117, 123));
然后开始分类预测,根据prototxt中的开始的要求,我们需要输入迭代10次,输出预测分类的结果,代码实现如下:
// 支持1000个图像分类检测
Mat prob;
// 循环10+
for (int i = 0; i < 10; i++)
{
// 输入
net.setInput(inputBlob, "data");
// 分类预测
prob = net.forward("prob");
}
// 读取分类索引,最大与最小值
Mat probMat = prob.reshape(1, 1); //reshape the blob to 1x1000 matrix // 1000个分类
Point classNumber;
double classProb;
minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber); // 可能性最大的一个
int classIdx = classNumber.x; // 分类索引号
printf("n current image classification : %s, possible : %.2f n", labels.at(classIdx).c_str(), classProb);
putText(testImage, labels.at(classIdx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);
imshow("Image Category", testImage);
其中读取图像分类索引与文本描述的方法代码如下:
vector<String> readClasslabels() {
std::vector<String> classNames;
std::ifstream fp(labelFile);
if (!fp.is_open())
{
std::cerr << "File with classes labels not found: " << labelFile << std::endl;
exit(-1);
}
std::string name;
while (!fp.eof())
{
std::getline(fp, name);
if (name.length())
classNames.push_back(name.substr(name.find(' ') + 1));
}
fp.close();
return classNames;
}
三:效果显示
航天飞机测试图像
霸气威武的J10战斗机
玩具店
足球场上
四:完全的源代码
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
using namespace cv;
using namespace cv::dnn;
using namespace std;
String modelTxt = "D:/vcprojects/images/dnn/bvlc_googlenet.prototxt";
String modelBin = "D:/vcprojects/images/dnn/bvlc_googlenet.caffemodel";
String labelFile = "D:/vcprojects/images/dnn/synset_words.txt";
vector<String> readClasslabels();
int main(int argc, char** argv) {
Mat testImage = imread("D:/vcprojects/images/dnn/football.jpg");
if (testImage.empty()) {
printf("could not load image...n");
return -1;
}
// create googlenet with caffemodel text and bin
Net net = dnn::readNetFromCaffe(modelTxt, modelBin);
if (net.empty())
{
std::cerr << "Can't load network by using the following files: " << std::endl;
std::cerr << "prototxt: " << modelTxt << std::endl;
std::cerr << "caffemodel: " << modelBin << std::endl;
return -1;
}
// 读取分类数据
vector<String> labels = readClasslabels();
//GoogLeNet accepts only 224x224 RGB-images
Mat inputBlob = blobFromImage(testImage, 1, Size(224, 224), Scalar(104, 117, 123));
// 支持1000个图像分类检测
Mat prob;
// 循环10+
for (int i = 0; i < 10; i++)
{
// 输入
net.setInput(inputBlob, "data");
// 分类预测
prob = net.forward("prob");
}
// 读取分类索引,最大与最小值
Mat probMat = prob.reshape(1, 1); //reshape the blob to 1x1000 matrix // 1000个分类
Point classNumber;
double classProb;
minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber); // 可能性最大的一个
int classIdx = classNumber.x; // 分类索引号
printf("n current image classification : %s, possible : %.2f n", labels.at(classIdx).c_str(), classProb);
putText(testImage, labels.at(classIdx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);
imshow("Image Category", testImage);
waitKey(0);
return 0;
}
/* 读取图像的1000个分类标记文本数据 */
vector<String> readClasslabels() {
std::vector<String> classNames;
std::ifstream fp(labelFile);
if (!fp.is_open())
{
std::cerr << "File with classes labels not found: " << labelFile << std::endl;
exit(-1);
}
std::string name;
while (!fp.eof())
{
std::getline(fp, name);
if (name.length())
classNames.push_back(name.substr(name.find(' ') + 1));
}
fp.close();
return classNames;
}
- 数论部分第二节:埃拉托斯特尼筛法 埃拉托斯特尼筛法
- [接口测试 -基础篇] 20 用flask写一个简单server用于接口测试
- 接口测试 | urllib篇 19 urllib基本示例
- 接口测试 | urllib篇 18 urllib介绍
- 【专知-Deeplearning4j深度学习教程01】分布式Java开源深度学习框架DL4j安装使用: 图文+代码
- .Net Core Runtime安装说明
- 【专知-Deeplearning4j深度学习教程02】用ND4J自己动手实现RBM: 图文+代码
- 【专知-Deeplearning4j深度学习教程03】使用多层神经网络分类MNIST数据集:图文+代码
- TypeScript 1.6发布:完全支持React/JSX
- 【专知-Java Deeplearning4j深度学习教程04】使用CNN进行文本分类:图文+代码
- sql server之数据库语句优化
- 【专知-Java Deeplearning4j深度学习教程05】无监督特征提取神器—AutoEncoder:图文+代码
- 平衡树初阶——AVL平衡二叉查找树+三大平衡树(Treap + Splay + SBT)模板【超详解】
- HDU 2689 Sort it【树状数组】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP单元测试配置与使用方法详解
- Windows平台PHP+IECapt实现网页批量截图并创建缩略图功能详解
- laravel 查询数据库获取结果实现判断是否为空
- 浅析PHP中的 inet_pton 网络函数
- php解压缩zip和rar压缩包文件的方法
- laradock环境docker-compose操作详解
- laravel中的fillable和guarded属性详解
- PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
- Laravel 6 将新增为指定队列任务设置中间件的功能
- Python生成器传参数及返回值原理解析
- PHP Swoole异步MySQL客户端实现方法示例
- PHP实现微信公众号验证Token的示例代码
- Laravel框架之解决前端显示图片问题
- thinkPHP5.1框架中Request类四种调用方式示例
- Python TestSuite生成测试报告过程解析