OpenCV 中使用Caffe中训练好的model

在OpenCV中使用Caffe中训练好的model

以 LeNet 为例子

第一步: 改写deploy文件

按下面的步骤修改文件 lenet_train_test.prototxt


(1) 去掉数据输入层,即top 为 “data” 的layers 去掉

      即将下面的内容删掉     

layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "examples/mnist/mnist_train_lmdb"
    batch_size: 64
    backend: LMDB
  }
}
layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "examples/mnist/mnist_test_lmdb"
    batch_size: 100
    backend: LMDB
  }
}

(2) 重新建立输入

     即添加下面的内容

input: "data"
input_shape {
  dim: 1   # batchsize
  dim: 1   # number of channels 
  dim: 28  # width
  dim: 28  # height
}


(3) 去掉输出层,即将bottom 为 “label” 的layers 去掉

     即将下面的内容删掉

     

layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "ip2"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip2"
  bottom: "label"
  top: "loss"
}


(4) 重新建立输出

   即添加下面的内容

layer {
  name: "prob"
  type: "Softmax"
  bottom: "ip2"
  top: "prob"
}

修改完后保存到文件中(mnist_deploy.prototxt,内容如下

name: "LeNet"
input: "data"
input_shape {
  dim: 1   # batchsize
  dim: 1   # number of channels
  dim: 28  # width
  dim: 28  # height
}
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 20
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 50
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "ip1"
  type: "InnerProduct"
  bottom: "pool2"
  top: "ip1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 500
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "ip1"
  top: "ip1"
}
layer {
  name: "ip2"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "prob"
  type: "Softmax"
  bottom: "ip2"
  top: "prob"
}


第二步:使用cv::dnn 里的API加载model, 输入图片,进行测试

代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>

using namespace std;
using namespace cv;
using namespace cv::dnn;

/* 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);
    Point classNumber;
    minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
    *classId = classNumber.x;
}

int main(int argc, char *argv[])
{
    string modelTxt = "../mnist_deploy.prototxt";
    string modelBin = "../lenet_iter_10000.caffemodel";
    string imgFileName = argc > 1 ? argv[1] : "../4.jpg";
    //read image
    Mat imgSrc = imread(imgFileName);
    if(imgSrc.empty()){
        cout << "Failed to read image " << imgFileName << endl;
        exit(-1);
    }
    Mat img;
    cvtColor(imgSrc, img, COLOR_BGR2GRAY);
    //LeNet accepts 28*28 gray image
    resize(img, img , Size(28, 28)); 
    //in the file "lenet_train_test.prototxt", in the Data input layer, we can see
    //  transform_param {
    //    scale: 0.00390625
    //  }
    //which means the input data need to be normalized before feed the data into the net
    // 0.00390625 = 1/255 after this operation, the value of the image pixel will be transferred to be one value between 0 and 1
    img /=255;

    //transfer image(1*28*28) to blob data with 4 dimensions(1*1*28*28) 
    Mat inputBlob = dnn::blobFromImage(img); 
    dnn::Net net; 
    try{ 
        net = dnn::readNetFromCaffe(modelTxt, modelBin); 
    }catch(cv::Exception &ee){ 
      cerr << "Exception: " << ee.what() << endl; 
      if(net.empty()){ 
         cout << "Can't load the network by using the flowing files:" << endl; 
         cout << "modelTxt: " << modelTxt << endl; 
         cout << "modelBin: " << modelBin << endl; exit(-1); 
      }
    } 
    Mat pred; 
    net.setInput(inputBlob, "data");//set the network input, "data" is the name of the input layer 
    pred = net.forward("prob");//compute output, "prob" is the name of the output layer 
    cout << pred << endl; int classId; double classProb; getMaxClass(pred, &classId, &classProb); 
    cout << "Best Class: " << classId << endl;
    cout << "Probability: " << classProb*100 << "%" << endl;
}


编译代码并运行,测试结果如下:


下面的代码是测试多张图片

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace std;
using namespace cv;
using namespace cv::dnn;
/* 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);
    Point classNumber;
    minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
    *classId = classNumber.x;
}
int main(int argc, char *argv[])
{
    string modelTxt = "../mnist_deploy.prototxt";
    string modelBin = "../lenet_iter_10000.caffemodel";
    if(argc < 2){
        cout << "Please input image file name!!!" << endl;
        return -1;
    }

    Mat inputBlob;
    vector<Mat> imgVec;
    for(int i = 1;  i < argc; i++){
        string imgFileName = argv[i];
        Mat imgSrc = imread(imgFileName);
        if(imgSrc.empty()){
            cout << "Failed to read image " << imgFileName << endl;
            exit(-1);
        }

        Mat img;
        cvtColor(imgSrc, img, COLOR_BGR2GRAY);
        resize(img, img , Size(28, 28));
        img /= 255; 
        imgVec.push_back(img);
    }
    inputBlob = dnn::blobFromImages(imgVec);
 
    dnn::Net net;
    try{
        net = dnn::readNetFromCaffe(modelTxt, modelBin);
    }catch(cv::Exception &ee){
        cerr << "" << ee.what() << endl;
        if(net.empty()){
            cout << "Can't load the network by using the flowing files:" << endl;
            cout << "modelTxt: " << modelTxt << endl;
            cout << "modelBin: " << modelBin << endl;
            exit(-1);
        }
    }

    Mat pred;
    net.setInput(inputBlob, "data");
    pred = net.forward("prob");
    cout << endl;
    cout << pred << endl;
    cout << endl;
    for(int i = 0; i < imgVec.size(); i++){
        int classId;
        double classProb;
        getMaxClass(pred.row(i), &classId, &classProb);
        cout << "The class id of image " << argv[i+1] << " is: " << classId << endl;
        cout << "The probability is: " << classProb*100 << "%" << endl;
    }
    cout << endl;

}


测试结果如下:


测试用到的几张图片:



注:本文中的代码所调用的API是基于OpenCV 3.3.0版本的






  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python OpenCV,Deep Neural Networks (DNN)模块提供了一种简单的方式来使用预先训练好的深度学习模型。该模块支持多种深度学习框架,如Caffe、TensorFlow等,并提供了一个方便的接口来加载和运行这些模型。使用DNN模块,可以很容易地在Python实现各种深度学习任务,如图像分类、对象检测、语义分割等。 下面是一个简单的例子,演示如何使用DNN模块进行对象检测: ```python import cv2 # 加载模型和标签 model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'model.caffemodel') labels = open('labels.txt').read().strip().split('\n') # 加载图像并进行预处理 image = cv2.imread('image.jpg') blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 0.007843, (300, 300), 127.5) # 运行模型并解析结果 model.setInput(blob) detections = model.forward() # 显示结果 for i in range(detections.shape[2]): confidence = detections[0, 0, i, 2] if confidence > 0.5: class_id = int(detections[0, 0, i, 1]) label = labels[class_id] box = detections[0, 0, i, 3:7] * np.array([image.shape[1], image.shape[0], image.shape[1], image.shape[0]]) (startX, startY, endX, endY) = box.astype("int") cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2) cv2.putText(image, label, (startX, startY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) cv2.imshow('Output', image) cv2.waitKey(0) ``` 在这个例子,我们加载了一个已经训练好的Caffe模型和对应的标签,然后加载一张图像并进行预处理。接下来,我们将输入图像传递给模型,并运行模型得到结果。最后,我们解析结果并将其可视化。这个例子演示了如何进行对象检测,但是使用DNN模块,可以实现更多的深度学习任务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值