OpenCV DNN模块模型推理(c++实现)

一、图像预处理

将原始图像转换为可以直接输入网络的格式,在进行深度学习时,blobFromImage主要是用来对图片进行预处理。

blobFromImage(InputArray image, 
			  double scalefactor=1.0, 
		      const Size& size = Size(),
			  const Scalar& mean = Scalar(), 
			  bool swapRB = false, 
			  bool crop = false,
			  int ddepth = CV_32F)

参数:

  • image:输入图像(1、3或者4通道)
  • scalefactor:图像各通道数值的缩放比例
  • size:输出图像的空间尺寸,如size=(200,300)表示高h=300,宽w=200
  • mean:用于各通道减去的值,以降低光照的影响(e.g. image为bgr3通道的图像,mean=[104.0, 177.0, 123.0],表示b通道的值-104,g-177,r-123)
  • swapRB:交换RB通道,默认为False.(cv2.imread读取的是彩图是bgr通道)
  • crop:图像裁剪,默认为False.当值为True时,先按比例缩放,然后从中心裁剪成size尺寸
  • ddepth:输出的图像深度,可选CV_32F 或者 CV_8U

返回:

函数返回4D矩阵(没有定义行/列值,因此这些值为-1)

注意:

1. 当同时进行scalefactor,size,mean,swapRB操作时,优先按swapRB交换通道,其次按scalefactor比例缩放,然后按mean求减,最后按size进行resize操作。

2. 当进行减均值操作时,ddepth不能选取CV_8U

3. 当crop=True时,调整输入图像的大小,使调整大小后的一侧等于相应的尺寸,另一侧等于或大于,然后从中心进行裁剪。

4、cv2.dnn.blobFromImages有更少的函数调用开销,能够更快批处理图像或帧。

代码示例:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

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

string path = "img.png"
// 读入原始图片
Mat input_image = readimg(path);
// 归一化+resize+COLOR_BGR2RGB
blobFromImage(input_image, blob, 1. / 255., Size(512, 512), Scalar(), true, false);

二、模型载入(以ONNX为例)

1、读取模型文件

readNet(const String& model,
        const String& config = "", 
        const String& framework = "");

参数:

  • model:需载入的模型权重文件,适用于以下模型格式(截至opencv4.6版本):

      `*.caffemodel` (Caffe, http://caffe.berkeleyvision.org/)

      `*.pb` (TensorFlow, https://www.tensorflow.org/)

      `*.t7` | `*.net` (Torch, http://torch.ch/)
      `*.weights` (Darknet, https://pjreddie.com/darknet/)
      `*.bin` (DLDT, https://software.intel.com/openvino-toolkit)
      `*.onnx` (ONNX, https://onnx.ai/)

  • config:网络配置文件,适用以下格式:

      `*.prototxt` (Caffe, http://caffe.berkeleyvision.org/)
      `*.pbtxt` (TensorFlow, https://www.tensorflow.org/)
      `*.cfg` (Darknet, https://pjreddie.com/darknet/)
      `*.xml` (DLDT, https://software.intel.com/openvino-toolkit)

  • framework:用于确定格式的显式框架名称标记

2、将图片输入到DNN网络中

setInput(InputArray blob, const String& name = "",
         double scalefactor = 1.0, const Scalar& mean = Scalar());
  • blob:输入经过blobFromImage处理的图像信息(支持CV_32F和CV_8U位深度)
  • name:输入层的名称,可选
  • scalefactor:标准化参数,可选
  • mean:各通道的平均减法值,可选

3、指定计算后台与设备

setPreferableBackend(int backendId);
setPreferableTarget(int targetId);

 参数:

  • backendId:指定计算后台,可填参数:

DNN_BACKEND_DEFAULT
DNN_BACKEND_INFERENCE_ENGINE
DNN_BACKEND_OPENCV

  •  targetId:指定计算设备,可填参数:

DNN_TARGET_CPU                 // 使用CPU推理
DNN_TARGET_OPENCL     
DNN_TARGET_OPENCL_FP16
DNN_TARGET_MYRIAD     
DNN_TARGET_FPGA
DNN_TARGET_CUDA               // 使用GPU推理
DNN_TARGET_CUDA_FP16

支持的后台与设备组合如下:

4、运行前向推理

forward(OutputArrayOfArrays outputBlobs,
        const std::vector<String>& outBlobNames);

 参数:

  • outputBlobs:输入空的vector<Mat>对象,用于返回推理结果
  • outBlobNames:输出层的名称

注意:

1、forward的函数原型有4个,分别提供了不同的功能,这里暂举了个典型的例子。

2、输出层名称可通过netron查看,或net.getUnconnectedOutLayersNames()获取。

代码示例:

Net net;
net = readNet("./models/XXX.onnx");
// 输入blob格式图片
net.setInput(blob);
// 使用cpu推理
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(DNN_TARGET_CPU);
// 前向推理
vector<Mat> outputs;
net.forward(outputs, net.getUnconnectedOutLayersNames());


参考链接:

https://blog.csdn.net/a1111111111ss/article/details/106070631

https://blog.csdn.net/weixin_42216109/article/details/103010206

https://blog.csdn.net/weixin_51244852/article/details/119214295

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值