C++ opencv-3.4.1 調(diào)用caffe訓(xùn)練好的模型

opencv在3.0之后就支持調(diào)用深度學(xué)習(xí)模型奋岁。OpenCV dnn模塊目前支持Caffe、TensorFlow荸百、Torch闻伶、PyTorch等深度學(xué)習(xí)框架。另外够话,新版本中使用預(yù)訓(xùn)練深度學(xué)習(xí)模型的API同時(shí)兼容C++和Python蓝翰。

參照官方教程進(jìn)行一個(gè)分類模型的調(diào)用caffe模型進(jìn)行分類,Load Caffe framework models女嘲。注意版本畜份,我的版本是3.4.1,選擇對(duì)應(yīng)版本欣尼。

image.png
  1. 在opencv的解壓文件下面有sample/dnn/所有的例子爆雹。這個(gè)例子來自sample/dnn//caffe_googlenet.cpp

  2. 下載兩個(gè)文件bvlc_googlenet.prototxt and bvlc_googlenet.caffemodel

3.也要下載 synset_words.txt.

  1. 把上面三個(gè)文件放在與caffe_googlenet.cpp同級(jí)目錄。

  2. 新建工程把caffe_googlenet.cpp添加進(jìn)去愕鼓。

caffe_googlenet.cpp 代碼

#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)
{
    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;
}

const char* params
= "{ help         | false | Sample app for loading googlenet model }"
"{ proto          | bvlc_googlenet.prototxt | model configuration }"
"{ model          | bvlc_googlenet.caffemodel | model weights }"
"{ label          | classification_classes_ILSVRC2012.txt | names of ILSVRC2012 classes }"
"{ image          | space_shuttle.jpg | path to image file }"
"{ opencl         | false | enable OpenCL }"
;

int main(int argc, char **argv)
{
    CV_TRACE_FUNCTION();

    CommandLineParser parser(argc, argv, params);

    if (parser.get<bool>("help"))
    {
        parser.printMessage();
        return 0;
    }

    String modelTxt = parser.get<string>("proto");
    String modelBin = parser.get<string>("model");
    String imageFile = parser.get<String>("image");
    String classNameFile = parser.get<String>("label");

    Net net;
    try {
        //! [Read and initialize network]
        net = dnn::readNetFromCaffe(modelTxt, modelBin);
        //! [Read and initialize network]
    }
    catch (const cv::Exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        //! [Check that network was read successfully]
        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);
        }
        //! [Check that network was read successfully]
    }

    if (parser.get<bool>("opencl"))
    {
        net.setPreferableTarget(DNN_TARGET_OPENCL);
    }

    //! [Prepare blob]
    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 BGR-images
    Mat inputBlob = blobFromImage(img, 1.0f, Size(224, 224),
        Scalar(104, 117, 123), false);   //Convert Mat to batch of images
    //! [Prepare blob]
    net.setInput(inputBlob, "data");        //set the network input
    Mat prob = net.forward("prob");         //compute output

    cv::TickMeter t;
    for (int i = 0; i < 10; i++)
    {
        CV_TRACE_REGION("forward");
        //! [Set input blob]
        net.setInput(inputBlob, "data");        //set the network input
        //! [Set input blob]
        t.start();
        //! [Make forward pass]
        prob = net.forward("prob");                          //compute output
        //! [Make forward pass]
        t.stop();
    }

    //! [Gather output]
    int classId;
    double classProb;
    getMaxClass(prob, &classId, &classProb);//find the best class
    //! [Gather output]

    //! [Print results]
    std::vector<String> classNames = readClassNames(classNameFile.c_str());
    std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
    std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
    //! [Print results]
    std::cout << "Time: " << (double)t.getTimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;
    // input samething
    int a;
    std::cin >> a;

    return 0;
} //main

按照對(duì)應(yīng)的版本使用例子钙态,一般不會(huì)出錯(cuò)。

這里有幾個(gè)比較重要的參數(shù)菇晃,需改對(duì)應(yīng)的參數(shù)就可進(jìn)行不同圖片的分類了册倒。

const char* params
= "{ help         | false | Sample app for loading googlenet model }"
"{ proto          | bvlc_googlenet.prototxt | model configuration }"
"{ model          | bvlc_googlenet.caffemodel | model weights }"
"{ label          | synset_words.txt | names of ILSVRC2012 classes }"
"{ image          | space_shuttle.jpg | path to image file }"
"{ opencl         | false | enable OpenCL }"

proto: caffe的配置文件
model:caffe的參數(shù)文件
image:圖片
opencl:是否使用opencl進(jìn)行加速

result

Attempting to upgrade input file specified using deprecated V1LayerParameter: bvlc_googlenet.caffemodel
Successfully upgraded file specified using deprecated V1LayerParameter
[ INFO:0] Initialize OpenCL runtime...

Net Outputs(1):
prob
Best class: #812 'shuttle'
Probability: 99.993%
Time: 1492.05 ms (average from 10 iterations)

使用c++ opencv調(diào)用tensorflow訓(xùn)練好的卷積神經(jīng)網(wǎng)絡(luò)
opencv官方教程caffe model調(diào)用
OpenCV調(diào)用TensorFlow預(yù)訓(xùn)練模型
基于opencv dnn模塊 的caffe模型的調(diào)用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市磺送,隨后出現(xiàn)的幾起案子驻子,更是在濱河造成了極大的恐慌灿意,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拴孤,死亡現(xiàn)場(chǎng)離奇詭異脾歧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)演熟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門鞭执,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人芒粹,你說我怎么就攤上這事兄纺。” “怎么了化漆?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵估脆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我座云,道長(zhǎng)疙赠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任朦拖,我火速辦了婚禮圃阳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘璧帝。我一直安慰自己捍岳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布睬隶。 她就那樣靜靜地躺著锣夹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苏潜。 梳的紋絲不亂的頭發(fā)上银萍,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音恤左,去河邊找鬼砖顷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赃梧,可吹牛的內(nèi)容都是我干的滤蝠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼授嘀,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼物咳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹄皱,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤览闰,失蹤者是張志新(化名)和其女友劉穎芯肤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體压鉴,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡崖咨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了油吭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片击蹲。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婉宰,靈堂內(nèi)的尸體忽然破棺而出歌豺,到底是詐尸還是另有隱情,我是刑警寧澤心包,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布类咧,位于F島的核電站,受9級(jí)特大地震影響蟹腾,放射性物質(zhì)發(fā)生泄漏痕惋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一娃殖、第九天 我趴在偏房一處隱蔽的房頂上張望血巍。 院中可真熱鬧,春花似錦珊随、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至禀崖,卻和暖如春衩辟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背波附。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工艺晴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掸屡。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓封寞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親仅财。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狈究,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355