OpenCV DNN模块官方教程地址如下,可以查看各个对应的使用方法。
https://docs.opencv.org/4.4.0/d2/d58/tutorial_table_of_content_dnn.html
OpenCV DNN模块官方文档分上面七个部分讲解,后续将选取其中部分在Windows平台做讲解讲解演示。
第一个部分:加载Caffe框架的模型。在本实例中,您将学习使用Caffe Model Zoo中用GoogLeNet训练的用于图像分类的模型来进行图像分类。
去掉一些命令行的代码,将核心代码提取如下,并做简单介绍与演示:
代码语言:javascript复制#include "pch.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace std;
using namespace cv;
using namespace dnn;
std::vector<std::string> classes;
int main(int argc, char** argv)
{
String model = "./bvlc_googlenet.caffemodel";
String config = "./bvlc_googlenet.prototxt";
String classesFile = "./classification_classes_ILSVRC2012.txt";
int backendId = 0;
int targetId = 0;
CV_Assert(!model.empty());
std::string file = classesFile;
std::ifstream ifs(file.c_str());
if (!ifs.is_open())
CV_Error(Error::StsError, "File " file " not found");
std::string line;
while (std::getline(ifs, line))
{
classes.push_back(line);
}
Net net = readNet(model, config);
static const std::string kWinName = "Deep learning image classification in OpenCV";
namedWindow(kWinName, WINDOW_NORMAL);
Mat img = imread("./test.jpg");
Mat blob;
float scale = 1.0;
Scalar mean = Scalar(104, 117, 123);
bool swapRB = true;
blobFromImage(img, blob, scale, Size(224, 224), mean, swapRB, false);
net.setInput(blob);
Mat prob = net.forward();
Point classIdPoint;
double confidence;
minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
int classId = classIdPoint.x;
// Put efficiency information.
std::vector<double> layersTimes;
double freq = getTickFrequency() / 1000;
double t = net.getPerfProfile(layersTimes) / freq;
std::string label = format("Inference time: %.2f ms", t);
putText(img, label, Point(0, 20), FONT_HERSHEY_SIMPLEX, 0.7, Scalar(255, 0, 0), 2);
// Print predicted class.
label = format("%s: %.4f", (classes.empty() ? format("Class #%d", classId).c_str() :
classes[classId].c_str()),
confidence);
cout << "label: " << classes[classId].c_str() << endl;
putText(img, label, Point(0, 45), FONT_HERSHEY_SIMPLEX, 0.7, Scalar(255, 0, 0), 2);
imshow(kWinName, img);
waitKey(0);
return 0;
}
使用方法与说明:
(1) 首先,下载GoogleNet模型文件和ILSVRC2012类名称文件并放入工作目录
bvlc_googlenet.prototxt、bvlc_googlenet.caffemodel、
classification_classes_ILSVRC2012.txt
(2) 使用.prototxt和.caffemodel文件的路径读取和初始化网络
代码语言:javascript复制 Net net = readNet(model, config, framework);
framework参数可以跳过,DNN模块可以根据model和config自动识别:
代码语言:javascript复制Net net = readNet(model, config);
(3) 读取输入图像并将其转换为GoogleNet可接受的Blob
代码语言:javascript复制blobFromImage(img, blob, scale, Size(224, 224), mean, swapRB, false);
(4) 将Blob传递到网络
代码语言:javascript复制net.setInput(blob);
(5) 向前传递
代码语言:javascript复制Mat prob = net.forward();
(6) 确定最佳类别
代码语言:javascript复制Point classIdPoint;
double confidence;
minMaxLoc(prob.reshape(1, 1), 0, &confidence, 0, &classIdPoint);
int classId = classIdPoint.x;
(7) 设置对应参数和文件路径运行测试,如下是测试效果(运行时间 类别):