opencv:DNN模块加载机器学习模型

DNN模块

从OpenCV 3.3开始,dnn模块加入到主仓库中,目前支持Caffe、TensorFlow、Torch、PyTorch等深度学习框架。

protobuf

Google Protocol Buffers,是google开发的的一套用于数据存储,网络通信时用于协议编解码的工具库。protobuf是一种灵活高效的独立于语言平台的结构化数据表示方法,类似json/xml。

TensoFlow模型

1. 模型文件
	a. 二进制的protobuf格式描述文件:.pb
	b. protobuf格式文本文件:.pbtxt
2. 加载训练好的模型:readNetFromTensorflow
dnn::Net net = cv::dnn::readNetFromTensorflow("xxx.pb");
3. 读取图像,并把图像转换
Mat img = imread("1.jpg", 1);
Mat inputBlob = dnn::blobFromImage(img, 0.00390625f, Size(256, 256), Scalar(), false,false); 
4. 把图像作为模型输入
net.setInput(inputBlob, "data");     
5. 前向传播(预测)
Mat pred = net.forward("fc2/prob");
6. 取出预测值最大

Caffe模型

1. 模型文件
	a. 模型文件.caffemodel
	b. 描述文件.prototxt
2. 加载模型:readNetFromCaffe

剩下的流程和tensorflow一样

加载网络模型

Net readNetFromTensorflow(const String &model, const String &config = String());
model:.pb文件
config:.pbtxt文件

Net readNetFromCaffe (const String &prototxt, const String &caffeModel=String())
prototxt:.prototxt文件
caffeModel:.caffemodel文件

图像转换为模型输入(图像缩放/裁剪/改变通道等,结果是4维的矩阵)

Mat blobFromImage(InputArray image, double scalefactor=1.0, const Size& size = Size(), const Scalar& mean = Scalar(), bool swapRB=true, bool crop=true);
image:输入的图像,可以是opencv的mat数据类型。
scalefactor:如果训练时,是归一化到0-1之间,那么这个参数就应该为0.00390625f (1/256),否则为1.0
size:应该与训练时的输入图像尺寸保持一致
mean:这个主要在caffe中用到,caffe中经常会用到训练数据的均值
swapRB:是否交换图像第1个通道和最后一个通道的顺序
crop:如果为true,就是裁剪图像,如果为false,就是等比例放缩图像

输入

void setInput (InputArray blob, const String &name = “”, double scalefactor = 1.0, const Scalar &mean = Scalar())
blob:输入数据
name:输入层的名字
scalefactor:缩放
mean:均值(像素值减去这个均值)

输出

Mat forward(const String& outputName = String());
outputName:输出层的名字

其它方式加载模型

Ptr cv::dnn::createTensorflowImporter(const String &model)
model:.pb文件

Ptr cv::dnn::createCaffeImporter(const String &prototxt, const String &caffeModel=String())
prototxt:.prototxt文件
caffeModel:.caffemodel文件

示例

Ptr<dnn::Importer> importer;
try
{
	importer = dnn::createCaffeImporter("xxx.prototxt", ".caffemodel");
}
catch (const cv::Exception &err) {
	cerr << err.msg << endl;
}
// 初始化
dnn::Net net;
importer->populateNet(net);
importer.release();

你可能感兴趣的:(opencv)