opencv3.4.3调用caffe分类模型
前言
opencv是图像领域中非常优秀的一个开源库,近年来,随着深度学习的发展,深度在图像识别、物体检测、语义分割等领域已经达到落地的程度。opencv开源库也一直在支持各种分类、检测model的调用,虽然还不够全面。。。opencv从3.3开始已经支持分类模型的调用,包括caffe、tensorflow、pytorch等框架训练出的模型。从3.4.2开始,支持yolov3的调用,这真的是一个很大的进步,可以把物体检测真正落地。
Opencv3.4.3调用caffe模型
那废话就不说了,直接上源代码吧,非常清晰明了。
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/utils/trace.hpp>
using namespace cv;
using namespace cv::dnn;
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
/* Find best class for the blob (i. e. class with maximal probability) */
static void getMaxClass(const Mat &probBlob, int *classId, double *classProb)
{
Mat probMat = probBlob.reshape(1, 1); //reshape the blob to 1x1000 matrix
Point classNumber;
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
*classId = classNumber.x;
}
static std::vector<String> readClassNames(const char *filename = "synset_words.txt")
{
std::vector<String> classNames;
std::ifstream fp(filename);
if (!fp.is_open())
{
std::cerr << "File with classes labels not found: " << filename << 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;
}
int main()
{
CV_TRACE_FUNCTION();
String modelTxt = "bvlc_googlenet.prototxt";
String modelBin = "bvlc_googlenet.caffemodel";
String imageFile = "cup_1.jpg";
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;
std::cerr << "bvlc_googlenet.caffemodel can be downloaded here:" << std::endl;
std::cerr << "http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel" << std::endl;
exit(-1);
}
Mat img = imread(imageFile);
if (img.empty())
{
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
exit(-1);
}
//GoogLeNet accepts only 224x224 RGB-images
Mat inputBlob = blobFromImage(img, 1, Size(224, 224),
Scalar(104, 117, 123)); //Convert Mat to batch of images
Mat prob;
cv::TickMeter t;
for (int i = 0; i < 10; i++)
{
CV_TRACE_REGION("forward");
net.setInput(inputBlob, "data"); //set the network input
t.start();
prob = net.forward("prob"); //compute output
t.stop();
}
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);//find the best class
std::vector<String> classNames = readClassNames();
std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
std::cout << "Time: " << (double)t.getTimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;
system("pause");
return 0;
}
关于代码中所用到的文件:bvlc_googlenet.caffemodel、bvlc_googlenet.prototxt、synset_words.txt
其中:bvlc_googlenet.caffemodel是模型文件,是GoogleNet在ImageNet上训练好的模型,bvlc_googlenet.prototxt是googleNet的结构文件,synset_words.txt是ImageNet上的类别信息。
实验结果
Best class: #812 'space shuttle'
Probability: 99.9828%
Time: 53.3045 ms (average from 10 iterations)
Best class: #504 'coffee mug'
Probability: 68.0434%
Time: 52.8983 ms (average from 10 iterations)