您的位置:首页 > Web前端

OpenCV dnn模块支持Caffe

2016-12-25 11:14 465 查看
#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";
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;
}
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);
}
dnn::Net net;
importer->populateNet(net);
importer.release(); //We don't need importer anymore
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
net.setBlob(".data", inputBlob); //set the network input
net.forward(); //compute output
dnn::Blob prob = net.getBlob("prob"); //gather output of "prob" layer
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;
return 0;
} //main

demo来自http://docs.opencv.org/master/d5/de7/tutorial_dnn_googlenet.html

应用会更加方便了

 


opencv:Load Caffe framework models


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

$ cd ~/opencv_caffe/build_opencv

$ cmake -DOPENCV_EXTRA_MODULES_PATH=~/opencv_caffe/opencv_contrib/modules ~/opencv_caffe/opencv-master

$ make -j8

编译完成,中途如果有什么错误可以留言,一起探讨。

然后就是dnn文件加下面的caffe模型加载了。还没有完成Linux下面的实现,win7下面实现已经完成。
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 cnn dnn caffe