OpenCV dnn模块支持Caffe

#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%


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值