- 💂 个人主页:风间琉璃
- 🤟 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主
- 💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦
目录
前言
一、加载网络模型
二、构建输入
三、执行推理
四、解析输出
前言
OpenCV DNN(Deep Neural Networks)模块是OpenCV库中的一个模块,用于在计算机视觉任务中使用深度神经网络模型。它提供了加载、推断和可视化使用各种深度学习框架(如Caffe、TensorFlow、Torch/PyTorch等)训练的模型的功能。
一般使用DNN模块进行部署有四大步骤:加载网络模型、构建输入、执行推理inference、解析输出。
OpenCV官方文档:OpenCV: Deep Neural Network module
一、加载网络模型
在opencv中提供了dnn::readNet()函数用于加载已经训练完成的模型
Net cv::dnn::readNet(const String & model,
const String & config = "",
const String & framework = ""
)
model:模型文件名称。
config:配置文件名称。
framework:框架种类。
该函数可以加载已经完成训练的深度学习网络模型,返回一个Net类型的变量。
函数第一个参数是模型文件的名称,文件以二进制的形式保存着网络模型中权重系数。不同框架的模型具有不同的扩展名,该函数能够加载的框架、框架文件扩展名以及框架的网络如下。
函数第二个参数是网络模型的配置文件,不同框架的模型具有不同的扩展名,参数默认值表示不需要读取配置文件。
最后一个参数是框架的种类,该函数可以根据文件的格式判断框架的种类,但是也可以通过第三个参数显示的给出框架的种类,参数默认值为空,表示根据文件格式判断框架种类。
dnn::readNet()函数返回的Net类型是一个神经网络模型的类,OpenCV 4在Net类中提供了多个函数用于处理神经网络的模型,例如得到网络的层数、每层网络的权重、通过网络预测结果等。
OpenCV中加载网络模型之后,可以设置计算后台与计算目标设备,OpenCV DNN模块支持这两个设置的相关API如下:
(1)设置计算后台
void cv::dnn::Net::setPreferableBackend (int backendId)
backendId 表示后台计算,常见参数如下:
DNN_BACKEND_DEFAULT (DNN_BACKEND_INFERENCE_ENGINE):表示默认使用intel的预测推断库(需要下载安装Intel® OpenVINO™ toolkit, 然后重新编译OpenCV源码,在CMake时候enable该选项方可), 可加速计算。
DNN_BACKEND_HALIDE
DNN_BACKEND_INFERENCE_ENGINE
DNN_BACKEND_OPENCV: 一般情况都是使用opencv dnn作为后台计算。
DNN_BACKEND_VKCOM
DNN_BACKEND_CUDA :使用GPU作为后台计算,可以加速。
(2)设置目标设备
void cv::dnn::Net::setPreferableTarget (int targetId)
常见的目标设备如下:
DNN_TARGET_CPU:其中表示使用CPU计算,默认是的
DNN_TARGET_OPENCL: 表示使用OpenCL加速
DNN_TARGET_OPENCL_FP16 :可以尝试
DNN_TARGET_MYRIAD :树莓派上的
DNN_TARGET_VULKAN
DNN_TARGET_FPGA :使用推理引擎的异构插件与CPU回退的FPGA设备
DNN_TARGET_CUDA :在GPU上使用;
DNN_TARGET_CUDA_FP16
利用opencv加速主要涉及两个函数的调用,使用opencv设置参数使用不同的运行后台程序,例如使用GPU,CPU。
dnnnet.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
dnnnet.setPreferableTarget(cv::dnn::DNN_BACKEND_CUDA);
二、构建输入
在进行深度学习或图片分类时,blobFromImage主要是用来对图片进行预处理。
images:输入图像,图像可以是单通道、三通道或者四通道。
scalefactor:图像像素缩放系数。
size:输出图像的尺寸
mean:像素值去均值化的数值。
swapRB:是否交换三通道图像的第一个通道和最后一个通道的标志。
crop:调整大小后是否对图像进行剪切的标志。
ddepth:输出图像的数据类型,可选参数为CV_32F或CV_8U。
该函数能够将任意尺寸和数据类型的图像转换成指定尺寸和数据类型。
该第一个参数是原始图像,图像可以是单通道、三通道或者四通道。
第二个参数是图像像素的缩放系数,是一个double类型的数据,参数默认是为1.0,表示不进行任何缩放。
第三个参数是输出图像的尺寸,一般为模型输入需要的尺寸。
第四个参数是像素值去均值化的数值,去均值化的目的是为了减少关照变化对图像中内容的影响,参数默认值为空,可以不输入任何参数。
第五个参数为是否交换三通道图像的第一个通道和最后一个通道的标志,由于RGB颜色空间图像在OpenCV中有两种颜色通道顺序,该参数可以实现RGB通道顺序和BGR通道顺序间的转换,参数默认是为false,表示不进行交换。
第六个参数是图像调整尺寸时是否剪切的标志,当该参数为true时,调整图像的尺寸使得图像的行(或者列)等于需要输出的尺寸,而图像的列(或者行)大于需要输出的尺寸,之后从图像的中心剪切出需要的尺寸作为结果输出;当该参数为false时,直接调整图像的行和列满足尺寸要求,不保证图像原始的横纵比,参数默认值为false。
最后一个参数是输出图像的数据类型,可选参数为CV_32F或CV_8U,参数默认值为CV_32F。
这是一个重载成员函数,为方便起见而提供。它与上述函数的区别仅在于它接受的参数。
opencv也同时支持对一系列图片进行操作
数据预处理后,就需要将数据送入网络模型中,在OpenCV中设置网络新的输入数据,使用setInput()函数。
blob:新的输入数据,数据类型为CV_32F或CV_8U。
name:输入网络层的名称。
scalefactor:可选的标准化比例
mean:可选的减数数值。
该函数可以重新设置网络的输入值,函数第一个参数为新的输入数据,数据类型必须是CV_32F或CV_8U。第二个参数是输入网络层的名称,该参数可以使用默认值。第三个参数是可选的标准化比例,默认值为1。第四个参数是可选的减数数值,默认值为Scalar(),表示缺省该参数。
三、执行推理
forward()函数,执行前向传输,输入参数为需要输出的网络层的名称,返回值为Mat类型数据。
这个函数只需要提供layer的name即可;函数返回一个Mat变量,返回值是指输入的layername首次出现的输出。默认输出整个网络的运行结果。
四、解析输出
这里就需要我们对部署的网络模型有一定的了解,主要是处理forward()函数输出层的结果。
以YOLOv4为例,YOLOv4网络的输出为矩形框,每个矩形框由一个向量表示,所有矩形框组成一个向量组。每个向量的长度为类别数 + 5个参数,这五个参数的前四个分别是矩形框在图像上的位置center_x, center_y, width, height(均为比例,范围在0-1之间),第五个参数是该矩形框可能包含物体的置信度。从向量的第六个参数开始,分别表示矩形框中物体对应每个类别的置信度。
我们需要根据其网络结构的输出,对参数处理,完成最终的目标检测任务。这里的后处理也是很重要的,同时也是难点。
参考文章:OpenCV 3.4.11 cv::dnn::Net::forward()函数第一个参数的理解 - 灰信网(软件开发博客聚合) (freesion.com)
结束语
感谢你观看我的文章呐~本次航班到这里就结束啦 🛬
希望本篇文章有对你带来帮助 🎉,有学习到一点知识~
躲起来的星星🍥也在努力发光,你也要努力加油(让我们一起努力叭)。
最后,博主要一下你们的三连呀(点赞、评论、收藏),不要钱的还是可以搞一搞的嘛~
不知道评论啥的,即使扣个666也是对博主的鼓舞吖 💞 感谢 💐