【caffe】OpenCV Load caffe model
上一篇,我們介紹了opencv_contrib中的模塊在windows下的編譯,也提到了其中的dnn模塊可以讀取caffe的訓練模型用于目標檢測,這里我們具體介紹一下如何使用dnn讀取caffe模型并進行目標分類。
代碼如下:(代碼主要來自參考[2]和[3]):
#include <opencv2/dnn.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> #include <fstream> #include <iostream> #include <cstdlib> /* Find best class for the blob (i. e. class with maximal probability) */ void getMaxClass(cv::dnn::Blob &probBlob, int *classId, double *classProb) {cv::Mat probMat = probBlob.matRefConst().reshape(1, 1); //reshape the blob to 1x1000 matrix cv::Point classNumber;cv::minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);*classId = classNumber.x; }std::vector<cv::String> readClassNames(const char *filename = "synset_words.txt") {std::vector<cv::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(int argc, char **argv) {void cv::dnn::initModule();cv::String modelTxt = "bvlc_googlenet.prototxt";cv::String modelBin = "bvlc_googlenet.caffemodel";cv::String imageFile = "space_shuttle.jpg";cv::dnn::Net net = cv::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);}//! [Prepare blob] cv::Mat img = cv::imread(imageFile, cv::IMREAD_COLOR);if (img.empty()){std::cerr << "Can't read image from the file: " << imageFile << std::endl;exit(-1);}cv::resize(img, img, cv::Size(224, 224)); cv::dnn::Blob inputBlob = cv::dnn::Blob(img); //Convert Mat to dnn::Blob image batch //! [Prepare blob] //! [Set input blob] net.setBlob(".data", inputBlob); //set the network input //! [Set input blob] //! [Make forward pass] net.forward(); //compute output //! [Make forward pass] //! [Gather output] cv::dnn::Blob prob = net.getBlob("prob"); //gather output of "prob" layer int classId;double classProb;getMaxClass(prob, &classId, &classProb);//find the best class //! [Gather output] //! [Print results] std::vector<cv::String> classNames = readClassNames();std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;std::cout << "Probability: " << classProb * 100 << "%" << std::endl;//! [Print results] return 0; } //main
1、首先需要下載GoogLeNet模型及分類相關文件,可以從官網下載(或復制粘貼): ??bvlc_googlenet.prototxt、bvlc_googlenet.caffemodel以及synset_words.txt.也可以直接下載我長傳的打包好的資源(包括了2中的圖片)
2、下載待檢測圖片文件,如下:
Buran space shuttle
3、讀取.protxt文件和.caffemodel文件:
cv::dnn::Net net = cv::dnn::readNetFromCaffe(modelTxt, modelBin);
4、檢查網絡是否讀取成功:
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);}
5、讀取圖片并將其轉換成GoogleNet可以讀取的blob:
cv::Mat img = cv::imread(imageFile, cv::IMREAD_COLOR);if (img.empty()){std::cerr << "Can't read image from the file: " << imageFile << std::endl;exit(-1);}cv::resize(img, img, cv::Size(224, 224)); cv::dnn::Blob inputBlob = cv::dnn::Blob(img); //Convert Mat to dnn::Blob image batch
6、將blob傳遞給網絡:
net.setBlob(".data", inputBlob); //set the network input
7、前向傳遞:
net.forward(); //compute output
8、分類:
getMaxClass(prob, &classId, &classProb);//find the best class
9、打印分類結果:
std::vector<cv::String> classNames = readClassNames();std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
運行,報錯如下:
找了很久,終于在參考[3]中找到了解決方案,原因是這里將圖像數據轉換成blob的方法來自于老版本,在新版本中不兼容。解決方法如下:將cv::dnn::Blob(img)?用cv::dnn::Blob::fromImages(img)替換掉。
修改后,再運行,結果如下:
參考:
[1] http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html
[2] http://blog.csdn.net/langb2014/article/details/50555910
[3] https://github.com/opencv/opencv_contrib/issues/749
-----------------------------------------
2017.07.24
總結
以上是生活随笔為你收集整理的【caffe】OpenCV Load caffe model的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【caffe】windows下vs201
- 下一篇: 【caffe】使用自己的图像数据训练le