opencv:Load Caffe framework models

这个是怎么编译扩展包的呢?

首先在here下载两个包:opencv_contrib和opencv ,

然后按照正常的方法把opencv编译好:

这里的opencv必须要这个链接的版本,我试了一下自己的版本是不可以编译的。

cd opencv
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=OFF -D WITH_OPENGL=OFF -D BUILD_TIFF=ON ..
make -j4
sudo make install
sudo sh -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig
echo "OpenCV ready to be used"
先编译安装了opencv然后就是将扩展包编译一下,中途编译时间挺长的。耐心等待...........................

扩展包contrib可以直接命令,也可使用cmake-gui编译,cmake-gui的使用参考opencv_contrib的read.md。

$ cd ~/opencv_caffe/build_opencv
$ cmake -DOPENCV_EXTRA_MODULES_PATH=~/opencv_caffe/opencv_contrib/modules ~/opencv_caffe/opencv-master
$ make -j8
编译完成,中途如果有什么错误可以留言,一起探讨。

然后就是dnn文件加下面的caffe模型加载了。

caffe_googlenet.cpp:

#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.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) */
void getMaxClass(dnn::Blob &probBlob, int *classId, double *classProb)
{
    Mat probMat = probBlob.matRefConst().reshape(1, 1); //reshape the blob to 1x1000 matrix
    Point classNumber;

    minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
    *classId = classNumber.x;
}

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(int argc, char **argv)
{
    String modelTxt = "bvlc_googlenet.prototxt";
    String modelBin = "bvlc_googlenet.caffemodel";
    String imageFile = (argc > 1) ? argv[1] : "space_shuttle.jpg";

    //! [Create the importer of Caffe model]
    Ptr<dnn::Importer> importer;
    try                                     //Try to import Caffe GoogleNet model
    {
        importer = dnn::createCaffeImporter(modelTxt, modelBin);
    }
    catch (const cv::Exception &err)        //Importer can throw errors, we will catch them
    {
        std::cerr << err.msg << std::endl;
    }
    //! [Create the importer of Caffe model]

    if (!importer)
    {
        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);
    }

    //! [Initialize network]
    dnn::Net net;
    importer->populateNet(net);
    importer.release();                     //We don't need importer anymore
    //! [Initialize network]

    //! [Prepare blob]
    Mat img = imread(imageFile);
    if (img.empty())
    {
        std::cerr << "Can't read image from the file: " << imageFile << std::endl;
        exit(-1);
    }

    resize(img, img, Size(224, 224));       //GoogLeNet accepts only 224x224 RGB-images
    dnn::Blob inputBlob = 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]
    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<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
关于cpp文件的一些解释

1、首先下载GoogLeNet model files: bvlc_googlenet.prototxt and bvlc_googlenet.caffemodel

    和 ILSVRC2012类名: synset_words.txt.

 2、导入一个caffe模型接口
    
    Ptr<dnn::Importer> importer;
    try //Try to import Caffe GoogleNet model
    {
    importer = dnn::createCaffeImporter(modelTxt, modelBin);
    }
    catch (const cv::Exception &err) //Importer can throw errors, we will catch them
    {
    std::cerr << err.msg << std::endl;
    }
3、通过接口创建和初始化网络
    dnn::Net net;
    importer->populateNet(net);
    importer.release(); //We don't need importer anymore

4、读取一张图片并转换到blob数据存储
    Mat img = imread(imageFile);
    if (img.empty())
    {
    std::cerr << "Can't read image from the file: " << imageFile << std::endl;
    exit(-1);
    }
    resize(img, img, Size(224, 224)); //GoogLeNet accepts only 224x224 RGB-images
    dnn::Blob inputBlob = dnn::Blob(img); //Convert Mat to dnn::Blob image batch
    首先我们resize图片和变换通道顺序,得到224x224x3的图片,然后转换为1x2x224x224的4维blob类型的数据

 5、将blob输入到网络
    net.setBlob(".data", inputBlob); //set the network input

    In bvlc_googlenet.prototxt the network input blob named as "data", therefore this blob labeled as ".data" in opencv_dnn API.
    Other blobs labeled as "name_of_layer.name_of_layer_output".

 6、进行前向传播
    net.forward(); //compute output

 During the forward pass output of each network layer is computed, but in this example we need output from "prob" layer only.

 7、获取概率值
    dnn::Blob prob = net.getBlob("prob"); //gather output of "prob" layer
    int classId;
    double classProb;
    getMaxClass(prob, &classId, &classProb);//find the best class
    We put the output of "prob" layer, which contain probabilities for each of 1000 ILSVRC2012 image classes, to the prob blob. And find the index of element with maximal value in this one. This index correspond to the class of the image.

 8、输出结果
    std::vector<String> classNames = readClassNames();
    std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
    std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
    For our image we get:

        Best class: #812 'space shuttle'

        Probability: 99.6378%



你可能感兴趣的:(opencv:Load Caffe framework models)