GoogleNet模型圖像分類


Googlenet模型進行圖像分類

 

 

 有三個文件需要下載:

 

 

 第一個是caffe模型,第二個是整個網絡的描述文件,第三個是1000種分類對應的名稱表

 

主要的API有以下:

     1.blobFromImage函數;

 

 

 

 

 

    

2.reshape()方法;

 

   一、作用:常使用在對矩陣的處理上

 

   二、函數特點:reshape函數是針對對目標函數取數據用於重新布局時,是按照列的方式來獲取數據的

 

   三、幾種常見使用方式:

        方式一:arr.reshape((m,n))            意思是把arr矩陣變成一個新的m行n列的矩陣

        方式二:arr.reshape(-1,1)              -1表示按照行的方式的獲取,結果形成一列

        方式三:arr.reshape(m,n,q)              得到多維數組

 

 

    

3.minMaxLoc函數;

 

 

     其它相關C++知識:

1.ofstream和ifstream讀文件用法介紹

https://www.cnblogs.com/Jack-Elvis/p/12171691.html

2.getline(cin, name) 逐行復制函數

https://www.cnblogs.com/Jack-Elvis/p/12171939.html

 

3.push方法與push_back方法

https://www.cnblogs.com/Jack-Elvis/p/12172511.html

 

 

代碼如下:

 

 1 #include <opencv2/opencv.hpp>
 2 #include <opencv2/dnn.hpp>
 3 #include <iostream>
 4 
 5 using namespace cv;
 6 using namespace cv::dnn;
 7 using namespace std;
 8 //導入卷積網路dnn的頭文件、創建dnn工作空間
 9 String model_bin_file = "L:/googlenet/bvlc_googlenet.caffemodel";
10 String model_txt_file = "L:/googlenet/bvlc_googlenet.prototxt";
11 String labels_txt_file = "L:/googlenet/synset_words.txt";
12 //讀取googlenet的三個文件,caffe模型二進制,網絡描述文本文件,1000種分類表格的名稱文件
13  
14 vector<String> readLabels(); //調用readLabels()
15 
16 int main(int argc, char** argv) {
17     Mat src = imread("L:dog.jpg");
18     if (src.empty()) {
19         printf("could not load image...\n");
20         return -1;
21     }
22     namedWindow("input image", CV_WINDOW_AUTOSIZE);
23     imshow("input image", src);
24     vector<String> labels = readLabels();
25     Net net = readNetFromCaffe(model_txt_file, model_bin_file);
26     //使用readNetFromCaffe方法讀取前面兩個模型文件
27     if (net.empty()) {
28         printf("read caffe model data failure...\n"); //讀取文件失敗
29         return -1;
30     }
31     Mat inputBlob = blobFromImage(src, 1.0, Size(224, 224), Scalar(104, 117, 123));
32     //blobFromImage函數:1.輸入圖像 2.縮放尺度 3.圖像大小  4.輸入圖的像素減去各通道的均值
33 
34     Mat prob;  //預測的准確率
35     for (int i = 0; i < 10; i++) {
36         net.setInput(inputBlob, "data"); 
37    //將inputBlob內容輸入到網絡的第一層的第一個input為data (與網絡的描述文件對應)
38         prob = net.forward("prob");  //將通過描述文件計算后的prob值賦給變量prob
39     }
40     Mat probMat = prob.reshape(1, 1); 
41     //reshape()方法將矩陣prob變成一行多列(這里是1000列)的矩陣probMat
42     Point classNumber;
43     double classProb;
44     minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber);
45     //minMaxLoc函數為尋找矩陣最大最小值及位置
46     // 參數: 1.帶尋找矩陣 2.最小值 3.最大值 4.最小值位置 5.最大值位置
47     int classidx = classNumber.x;  //找出最大值的行數
48     printf("\n current image classification : %s, possible : %.2f", labels.at(classidx).c_str(), classProb);
49     // labels.at(classidx) 是最大行對應的labels標簽  .c_str()是將內容轉換為字符串型
50     putText(src, labels.at(classidx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255), 2, 8);
51     imshow("Image Classification", src);
52 
53     waitKey(0);
54     return 0;
55 }
56 
57 vector<String> readLabels() {
58     vector<String> classNames; //定義分類名稱變量(labels_name)
59     ifstream fp(labels_txt_file); //文件輸出流的方式讀取label words
60     if (!fp.is_open()) {          //文件不能打開
61         printf("could not open the file");
62         exit(-1); //非正常退出,返回值為-1
63     }
64     string name;
65     while (!fp.eof()) {      //如果沒有讀到文件尾部
66         getline(fp, name);   //getline函數逐行復制給name(空格不作為分隔符)
67         if (name.length()) {   //如果name.length有值
68             classNames.push_back(name.substr(name.find(' ') + 1));
69             //name.find()方法找到name中所有空格+1的位置
70             //name.substr()方法截取name中空格+1位置后面的字符串
71             //classNames.push_back()方法將所有行截取的字符以堆棧壓入className    
72         }
73     }
74     fp.close();          //關閉文件
75     return classNames;   //返回值為className
76 }

 

 

 

輸出結果:

 

 

 

 

 

 

 

 

 


免責聲明!

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



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