opencv3.3+dnn+caffe深度学习来实现图片的分类识别

https://blog.csdn.net/maweifei/article/details/78232503

https://blog.csdn.net/guyuealian/article/details/80570120

https://blog.csdn.net/xingchenbingbuyu/article/details/78416887

https://blog.csdn.net/zhxx120/article/details/78765422#comments

https://github.com/opencv/opencv/blob/master/samples/dnn/mobilenet_ssd_accuracy.py

https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md

https://www.pyimagesearch.com/2017/08/21/deep-learning-with-opencv/

源代码如下:

#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); //reshapethe blob to 1x1000 matrix

    Point classNumber;

 

    minMaxLoc(probMat,NULL, classProb, NULL, &classNumber);

    *classId = classNumber.x;

}

 

staticstd::vector<String> readClassNames(const char *filename= "F:/work/opencv/DNN/synset_words.txt")

{

    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;

}

 

intmain(int argc, char **argv)

{

    CV_TRACE_FUNCTION();

 

    String modelTxt = "F:/work/opencv/DNN/bvlc_googlenet.prototxt";

    String modelBin = "F:/work/opencv/DNN/bvlc_googlenet.caffemodel";

    //! [Read and initialize network]

    Net net =dnn::readNetFromCaffe(modelTxt, modelBin);

    //! [Read and initialize network]

    waitKey(0);

 

    //! [Check that network was read successfully]

    if (net.empty())

    {

        std::cerr << "Can't load network by using thefollowing 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]

 

    //! [Prepare blob]

    Mat img = imread("F:/work/opencv/data/boat.jpg", WINDOW_AUTOSIZE);

    waitKey(0);

    if (img.empty())

    {

        std::cerr<< "Can't read image from the file: " <<std::endl;

        exit(-1);

    }

 

    //GoogLeNet accepts only 224x224 RGB-images

    Mat inputBlob =blobFromImage(img, 1, Size(224, 224),

        Scalar(104, 117, 123));   //Convert Mat tobatch of images

                                  //! [Prepare blob]

 

    Mat prob;

    cv::TickMeter t;

    for (int i = 0; i < 10; i++)

    {

        CV_TRACE_REGION("forward");

        //! [Set input blob]

        net.setInput(inputBlob,"data");        //setthe network input

                                                //! [Set input blob]

        t.start();

        //! [Make forward pass]

        prob= net.forward("prob");              //computeoutput

                                                //! [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();

 

    putText(img,classNames.at(classId), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0, 255), 2, 8);

    namedWindow("Image Category",WINDOW_NORMAL);

    imshow("Image Category",img);

 

    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;

    waitKey(0);

    return 0;

} //main

对程序的部分解读

1、  首先,下载GoogLeNet模块文件: bvlc_googlenet.prototxt 和 bvlc_googlenet.caffemodel;另外你还需要一个 ILSVRC2012 类名的文件:synset_words.txt。把这三个文件放在程序的工作目录里

2、  使用.prototxt和.caffemodel路径文件来读取并初始化网络

net= dnn::readNetFromCaffe(modelTxt,modelBin);

3、  检查网络是否读取成功

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);

   }

4、  读取输入的图像,并转换成GoogleNet能接受的数据格式(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));

首先,我们缩放图像,并且改变图像的通道顺序,现在呢图像实际上就是一个224x224x3的3维阵列;接下来,通过使用特定的函数 cv::dnn::blobFromImages再把这个图像转换成一个1x3x224x224形状的4维对象(blob)。

5、  把这个对象(blob)传给网络

net.setInput(inputBlob,"data"); //setthe network input

在bvlc_googlenet.prototxt文件里,网络输入对象称为数据,因此在opencv_dnn api接口里,这个标记过的对象也称为数据,不过其他标记过的对象称为层名或输出层名。

6、  做前向传输

prob = net.forward("prob");

在前向传输过程中,每一个网络层的输出都被计算,但在本例程中我们仅从“prob”层输出

7、  决策判断出最佳分类

int classId;

double classProb;

getMaxClass(prob, &classId, &classProb);//find the bestclass

我们把”prob”层的输出放在probblob上,接着找出最大值元素的索引号,此索引号就是与识别到的图像类相关。

8、  在原图像上写上分类标识名

putText(img,classNames.at(classId), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0,255), 2, 8);

         namedWindow("Image Category",WINDOW_NORMAL);

imshow("Image Category", img);

9、  打印结果

识别为独木舟,并在原图像上打印出来,其概率为52.6929%

若喜欢我的文章请关注下我的公众号

 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值