opencv实现opencv3.3.0的DNN模块功能

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

代码:

#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 std::vector<String> readClasslabels(const char *filename = "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;
}

String modelTxt = "bvlc_googlenet.prototxt";

String modelBin = "bvlc_googlenet.caffemodel";

String labelFile = "synset_words.txt";

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

    Mat testImage = imread(argv[1], 1);

    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+
    cv::TickMeter t;
    for (int i = 0; i < 10; i++)

    {

        CV_TRACE_REGION("forward");
        net.setInput(inputBlob, "data");        //set the network input
        t.start();
        prob = net.forward("prob");                          //compute output
        t.stop();

    }

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

    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; // 分类索引号

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

    imshow("Image Category", testImage);

    std::cout << "Best class: #" << classIdx << " '" << labels.at(classIdx) << "'" << std::endl;
    std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
    std::cout << "Time: " << (double)t.getTimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;

    waitKey(0);

    return 0;
}
效果:



  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值