天天看點

GoogleNet模型圖像分類

Googlenet模型進行圖像分類

GoogleNet模型圖像分類

 有三個檔案需要下載下傳:

GoogleNet模型圖像分類

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

GoogleNet模型圖像分類

主要的API有以下:

     1.blobFromImage函數;

GoogleNet模型圖像分類
GoogleNet模型圖像分類

2.reshape()方法;

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

   二、函數特點:reshape函數是針對對目标函數取資料用于重新布局時,是按照列的方式來擷取資料的

   三、幾種常見使用方式:

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

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

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

3.minMaxLoc函數;

GoogleNet模型圖像分類

     其它相關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 }      

輸出結果:

GoogleNet模型圖像分類
GoogleNet模型圖像分類