开发环境
VS2013 + OpenCV3.4.1 + Qt5.8.0 + Caffe
实验准备
lenet_iter_5000.caffemodel // Caffe使用LeNet网络结构迭代训练5000次的model
lenet_iter_10000.caffemodel // Caffe使用LeNet网络结构迭代训练10000次的model
lenet_train_test.prototxt // LeNet的网络结构配置
以上数据可以由《Caffe初体验之Caffe-Windows的配置(CPU/GPU)与Mnist数据集测试》这篇文章的实验得到,在这篇文章的最后训练MNIST数据集成功后会得到lenet_iter_5000.caffemodel和lenet_iter_10000.caffemodel,如下图:
lenet_train_test.prototxt(开头和结尾)的内容需要修改,备份一个lenet_train_test.prototxt后进行修改,修改过程如下图:
主要代码
// Start```
string modelTxt = "caffe_mnist_model/lenet_train_test.prototxt";
string modelBin = "caffe_mnist_model/lenet_iter_10000.caffemodel";
if (frame.empty()){
ui.textBrowser->append("Image is empty.");
return;
}
Mat inputBlob = dnn::blobFromImage(frame, 0.00390625f/*1*/, Size(28, 28), Scalar(), false); //Convert Mat to batch of images
dnn::Net net;
try{
net = dnn::readNetFromCaffe(modelTxt, modelBin);
}catch (cv::Exception &ee){
ui.textBrowser->append("Exception:");
ui.textBrowser->append(ee.what());
if (net.empty()){
ui.textBrowser->append("Can't load the network by using the flowing files.");
return;
}
}
Mat pred;
net.setInput(inputBlob, "data");// data为lenet_train_test.prototxt下的input: "data"
// pred 为一个10*1的一维数组,其值为分类的概率
pred = net.forward("prob"); // 前向传播 prob为lenet_train_test.prototxt下的最后一个layer的name: "prob"
int classId;
double classProb;
getMaxClass(pred, &classId, &classProb);
// End```
ui.textBrowser->append(QString::fromLocal8Bit("识别结果: ") + QString::number(classId));
ui.textBrowser->append(QString::fromLocal8Bit("匹配概率: ") + QString::number(classProb * 100) + "%");
pred的数据结构如下图:
实验效果
只要写的数字不是太坑爹,基本可以正确识别,来两张截图如下:
总结
效果比我之前基于KNN《KNN实现手写数字识别》和基于SVM《SVM实现手写数字识别》的效果好非常多。可见传统的分类器逊色于deeplearning。
附件
源代码工程戳这里(注:release下的可执行程序可以直接运行)。
参考
https://www.cnblogs.com/messier/p/7997951.html