前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV3.3深度学习模块(DNN)应用-图像分类

OpenCV3.3深度学习模块(DNN)应用-图像分类

作者头像
OpenCV学堂
发布2018-04-04 11:24:44
1.6K0
发布2018-04-04 11:24:44
举报

DNN模块介绍

在OpenCV3.3版本发布中把DNN模块从扩展模块移到了OpenCV正式发布模块中,当前DNN模块最早来自Tiny-dnn,可以加载预先训练好的Caffe模型数据,OpenCV做了近一步扩展支持所有主流的深度学习框架训练生成与导出模型数据加载,常见的有如下:

  • Caffe
  • TensorFlow
  • Torch/PyTorch

OpenCV中DNN模块已经支持与测试过这些常见的网络模块

  • AlexNet
  • GoogLeNet v1 (also referred to as Inception-5h)
  • ResNet-34/50/...
  • SqueezeNet v1.1
  • VGG-based FCN (semantical segmentation network)
  • ENet (lightweight semantical segmentation network)
  • VGG-based SSD (object detection network)
  • MobileNet-based SSD (light-weight object detection network)

一:GoogleNet Caffe模型数据说明

OpenCV通过支持加载这些预先训练好的模型,实现图像分类、对象检测、语义分割、风格迁移等功能。支持Android/iOS等移动端平台开发。下面我们就以OpenCV3.3 使用Caffe的GoogleNet数据模型为例,实现对图像常见分类,OpenCV3.3的DNN模块使用的模型支持1000种常见图像分类、googlenet深度学习网络模型是2014图像分类比赛的冠军、首先是下载相关的数据模型文件

  • bvlc_googlenet.caffemodel
  • bvlc_googlenet.prototxt

其中prototxt是一个文本的JSON文件、一看就明白啦,另外一个文件二进制文件。文本文件只有你下载了OpenCV3.3解压缩之后就会在对应的目录发现。模型文件需要从以下地址下载即可: http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel

二:编程实现

首先我们需要加载它官方指定的一张测试图像space_shuttle.jpg 是一张航天飞机的图片、OpenCV中加载图像的代码如下:

代码语言:javascript
复制
      Mat testImage = imread("D:/vcprojects/images/dnn/football.jpg");

    if (testImage.empty()) {

        printf("could not load image...\n");

        return -1;

    }

然后我们需要声明模型数据的路径与标记数据路径,加载创建网络模型,代码实现如下:

代码语言:javascript
复制
  // create googlenet with caffemodel text and bin

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

    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;

        return -1;

    }


    // 读取分类数据

    vector<String> labels = readClasslabels();


    //GoogLeNet accepts only 224x224 RGB-images

    Mat inputBlob = blobFromImage(testImage, 1, Size(224, 224), Scalar(104, 117, 123));

然后开始分类预测,根据prototxt中的开始的要求,我们需要输入迭代10次,输出预测分类的结果,代码实现如下:

代码语言:javascript
复制
// 支持1000个图像分类检测

    Mat prob;

    // 循环10+

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

    {

        // 输入

        net.setInput(inputBlob, "data");        

        // 分类预测

        prob = net.forward("prob"); 

    }


    // 读取分类索引,最大与最小值

    Mat probMat = prob.reshape(1, 1); //reshape the blob to 1x1000 matrix // 1000个分类

    Point classNumber;

    double classProb;


    minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber); // 可能性最大的一个

    int classIdx = classNumber.x; // 分类索引号

    printf("\n current image classification : %s, possible : %.2f \n", labels.at(classIdx).c_str(), classProb);


    putText(testImage, labels.at(classIdx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);

    imshow("Image Category", testImage);

其中读取图像分类索引与文本描述的方法代码如下:

代码语言:javascript
复制
vector<String> readClasslabels() {

    std::vector<String> classNames;

    std::ifstream fp(labelFile);

    if (!fp.is_open())

    {

        std::cerr << "File with classes labels not found: " << labelFile << 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;

}

三:效果显示

航天飞机测试图像

霸气威武的J10战斗机

玩具店

足球场上

四:完全的源代码

代码语言:javascript
复制
#include <opencv2/opencv.hpp>

#include <opencv2/dnn.hpp>

#include <iostream>


using namespace cv;

using namespace cv::dnn;

using namespace std;


String modelTxt = "D:/vcprojects/images/dnn/bvlc_googlenet.prototxt";

String modelBin = "D:/vcprojects/images/dnn/bvlc_googlenet.caffemodel";

String labelFile = "D:/vcprojects/images/dnn/synset_words.txt";


vector<String> readClasslabels();

int main(int argc, char** argv) {

    Mat testImage = imread("D:/vcprojects/images/dnn/football.jpg");

    if (testImage.empty()) {

        printf("could not load image...\n");

        return -1;

    }


    // create googlenet with caffemodel text and bin

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

    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;

        return -1;

    }


    // 读取分类数据

    vector<String> labels = readClasslabels();


    //GoogLeNet accepts only 224x224 RGB-images

    Mat inputBlob = blobFromImage(testImage, 1, Size(224, 224), Scalar(104, 117, 123)); 


    // 支持1000个图像分类检测

    Mat prob;

    // 循环10+

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

    {

        // 输入

        net.setInput(inputBlob, "data");        

        // 分类预测

        prob = net.forward("prob"); 

    }


    // 读取分类索引,最大与最小值

    Mat probMat = prob.reshape(1, 1); //reshape the blob to 1x1000 matrix // 1000个分类

    Point classNumber;

    double classProb;


    minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber); // 可能性最大的一个

    int classIdx = classNumber.x; // 分类索引号

    printf("\n current image classification : %s, possible : %.2f \n", labels.at(classIdx).c_str(), classProb);


    putText(testImage, labels.at(classIdx), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);

    imshow("Image Category", testImage);


    waitKey(0);

    return 0;

}


/* 读取图像的1000个分类标记文本数据 */

vector<String> readClasslabels() {

    std::vector<String> classNames;

    std::ifstream fp(labelFile);

    if (!fp.is_open())

    {

        std::cerr << "File with classes labels not found: " << labelFile << 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;

}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DNN模块介绍
  • 一:GoogleNet Caffe模型数据说明
  • 二:编程实现
  • 三:效果显示
  • 四:完全的源代码
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档