zoukankan      html  css  js  c++  java
  • 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...
    ");
    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...
    "); //读取文件失败
    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("
     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 }

    输出结果:

  • 相关阅读:
    Android调用Webserive
    SSD算法思想和结构详解
    第五章-一起看决策树如何做出决策?
    第四章-朴素贝叶斯朴素吗?
    第三章-KNN(分类和回归算法模型)
    第二章-感知机
    第一章-统计学习方法概论
    c语言 宏定义和全局变量,认识循环语句
    运算符注意事项
    c语言的scanf函数注意事项
  • 原文地址:https://www.cnblogs.com/Jack-Elvis/p/12168927.html
Copyright © 2011-2022 走看看