基於【OpenCV3.4】GoogleNet Caffe進行圖片分類


#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iostream>
#include <fstream>
#include <opencv2/dnn/dnn.hpp>
#include <highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;
using namespace cv::dnn;

string model_txt = "bvlc_googlenet.prototxt";
String model_bin = "bvlc_googlenet.caffemodel";
string label_file = "synset_words.txt"; // 類別標簽表

vector<String> readLabels();
int main(int argc, char* argv[])
{
    // 1.加載圖片
    Mat src = imread("test1.jpg");
    if (src.empty())
    {
        cout << "The image is empty, please check it." << endl;
        return -1;

    }
    imshow("test1", src);

    // 2.加載caffe模型
    Net net = readNetFromCaffe(model_txt, model_bin);
    if (net.empty())
    {
        cout << "load net model data failed..." << endl;
        return -1;
    }

    // 3.讀入分類標簽
    vector<String> labels = readLabels();

    // 4.將輸入圖像轉換成GoogleNet可識別的blob格式
    Mat inputblob = blobFromImage(src, 1.0, Size(224, 224), Scalar(255, 0, 0));

    // 5.預測
    Mat prob_result;
    for (int i = 0; i < 10; i++) { // 進行10次預測,取可能性最大的類別
        net.setInput(inputblob, "data");
        prob_result = net.forward("prob");
    }
    Mat probMat = prob_result.reshape(1, 1); // 1-channel,1-rows, 變成1行10列
    Point class_position; 
    double class_probability; 
    minMaxLoc(probMat, NULL, &class_probability, NULL, &class_position); // 找出最大的可能性及其位置

    // 打印最大可能性的值
    int classidx = class_position.x;
    printf("\n current image classification : %s, possible : %.2f", labels.at(classidx).c_str(), class_probability);

    // 在圖上打印類別
    putText(src, labels.at(classidx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255), 2, 8);
    imshow("Image Classification", src);

    waitKey();
    return 0;
}
vector<String> readLabels()
{
    vector<String> classNames;
    ifstream in(label_file);

    if (!in.is_open()) 
    { 
        cout << "標簽文件不能打開" << endl; 
        exit(-1); 
    }
    string name;
    while (!in.eof())// 直至到達文件尾
    {
        getline(in, name); // 讀取一行
        if (!name.empty())
        {
            // 將描述分類前的數字去掉
            classNames.push_back(name.substr(name.find(' ') + 1));// 復制制定位置、長度的子字符串
        }
    }
    in.close();
    return classNames;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM