Bootstrap

《OpenCV计算机视觉》—— 使用DNN模块实现图片风格迁移

OpenCV中的DNN模块

OpenCV中的DNN(Deep Neural Network)模块是一个功能强大的工具,它允许开发者在计算机视觉应用中使用深度学习模型。以下是对OpenCV DNN模块的详细介绍:

一、功能概述

DNN模块的主要功能是载入其他深度学习框架(如TensorFlow、Caffe、Torch等)中已经训练好的模型,并使用这些模型完成预测等工作。它支持多种深度学习框架和模型格式,并提供了高效的推理能力。此外,DNN模块还与OpenCV的其他模块无缝集成,便于在计算机视觉项目中使用。

二、支持的模型格式

OpenCV的DNN模块支持多种深度学习模型格式,包括但不限于:

  1. Caffe:.caffemodel(模型权重文件)和.prototxt(模型配置文件)。
  2. TensorFlow:.pb(冻结的图文件)、.pbtxt(文本图文件)。
  3. Torch:.t7(Torch7模型)。
  4. ONNX:.onnx(ONNX模型)。
  5. Darknet:.cfg(配置文件)和.weights(权重文件)。
  6. PyTorch:通过ONNX格式导出。

三、基本使用方法

使用OpenCV的DNN模块进行推理的基本步骤如下:

  1. 加载预训练的模型和相应的配置文件

    • 使用cv2.dnn.readNetFromCaffe()加载Caffe模型。
    • 使用cv2.dnn.readNetFromTensorflow()加载TensorFlow模型。
    • 使用cv2.dnn.readNetFromTorch()加载Torch模型。
    • 使用cv2.dnn.readNetFromONNX()加载ONNX模型等。
  2. 对输入图像进行预处理

    • 使用cv2.dnn.blobFromImage()函数将图像转换为DNN模型所需的输入blob,并进行必要的缩放和归一化。
    • 函数cv2.dnn.blobFromImage:实现图像预处理,从原始图像构建一个符合人工神经网络输入格式的四维块。
      blob = cv2.dnn.blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None)
      
    • 参数:
      • image:表示输入图像。
      • scalefactor:表示对图像内的数据进行缩放的比例因子。具体运算是每个像素值*scalefactor,该值默认为 1。
      • size:用于控制blob的宽度、高度。
      • mean:表示从每个通道减去的均值。 (0,0,0):表示不进行均值减法。即不对图像的B、G、R通道进行任何减法操作。若输入图像本身是B、G、R通道顺序的,并且下一个参数swapRB值为True,则mean值对应的通道顺序为R、G、B。
      • swapRB:表示在必要时交换通道的R通道和B通道。一般情况下使用的是RGB通道。而openCV通常采用的是BGR通道,因此可以根据需要交换第1个和第3个通道。该值默认为False。
      • crop:布尔值,如果为True,则在调整大小后进行居中裁剪。
    • 返回值:
      • blob: 表示在经过缩放、裁剪、减均值后得到的符合人工神经网络输入的数据。该数据是一个四维数据,布局通常使用N(表示batch size)、C(图像通道数,如RGB图像具有三个通道)、H(图像高度)、W(图像宽度)表示
  3. 进行推理

    • 使用net.setInput(blob)设置输入。
    • 使用output = net.forward()进行推理,forward函数返回模型的输出。
  4. 解析和处理输出结果

    • 输出的处理方式取决于具体的应用。例如,对于图像分类任务,输出通常是一个概率分布,表示每个类别的概率;对于目标检测任务,输出通常包括检测到的对象的边界框和类别。

四、DNN 模块的特点

  • 轻量: OpenCV 的深度学习模块只实现了模型推理功能,不涉及模型训练,这使得相关程序非常精简,加速了安装和编译过程。
  • 外部依赖性低:重新实现一遍深度学习框架使得 DNN 模块对外部依赖性极低,极大地方便了深度学习应用的部署。
  • 方便:在原有 OpenCV 开发程序的基础上,通过 DNN 模块可以非常方便地加入对神经网络推理的支持。
  • 集成:若网络模型来自多个框架,如一个来自 TensorFlow,另外一个来自 Caffe,则 DNN 模块可以方便地对网络进行整合。
  • 通用性:DNN 模块提供了统一的接口来操作网络模型,内部做的优化和加速适用于所有网络模型格式,支持多种设备和操作系统。

五、常见应用示例

  1. 图像分类:使用DNN模块进行图像分类的典型步骤包括加载预训练的分类模型、预处理输入图像、进行推理以及解析和显示分类结果。
  2. 目标检测:目标检测任务通常包括加载预训练的检测模型、预处理输入图像、进行推理以及解析检测结果并绘制检测到的对象边界框。
  3. 图像分割:图像分割任务的步骤与分类和检测类似,但输出通常是一个掩码图像,表示每个像素的类别。
  4. 风格迁移:基于深度学习技术的图像处理方法,它允许将一张图片(风格图)中的风格、纹理迁移到另一张图片(内容图)上,同时保留内容图原有的主体结构。

示例:图片风格迁移

  • 图片的风格迁移就是运用OpenCV中的DNN模块中的方法,引用别人已经训练好的不同风格模型,将自己的图片以另一种风格展现出来

  • 例如将下图中左边的图片以右边的风格展示出来
    在这里插入图片描述

  • 以下链接中提供了几个由Torch训练出来的模型

  • 代码实现

    import cv2
    
    image_yuantu = cv2.imread("wechat.jpg")	# 读取图片
    # 将图片的大小缩小,可选,根据自己的图片大小决定
    image = cv2.resize(image_yuantu, dsize=None, fx=0.5, fy=0.5)
    cv2.imshow('yuan tu', image)	# 显示图片
    cv2.waitKey(0)
    
    """ -----------图片预处理------------------ """
    
    (h, w) = image.shape[:2]    # 获取图像尺寸
    blob = cv2.dnn.blobFromImage(image, 1, (w, h), (0, 0, 0), swapRB=True, crop=False)
    
    """ ---------------------加载模型------------------------- """
    
    net = cv2.dnn.readNet(r'model\starry_night.t7')	# 统一的调用方法
    # net = cv2.dnn.readNetFromTorch(r'.\model\la_muse.t7')
    # net = cv2.dnn.readNetFromTorch(r'.\model\candy.t7')
    # net = cv2.dnn.readNetFromTorch(r'.\model\composition_vii.t7')
    # net = cv2.dnn.readNetFromTorch(r'.\model\feathers.t7')
    # net = cv2.dnn.readNetFromTorch(r'.\model\udnie.t7')
    # net = cv2.dnn.readNetFromTorch(r'.\model\the_scream.t7')
    
    # 设置神经网络的输入
    net.setInput(blob)
    # 对输入图像进行前向传播,得到输出结果
    out = net.forward()
    # 将输出结果转换为合适的格式
    # out是四维的:B*C*H*W
    # B:batch图像数量(通常为1),C:channels通道数,H:height高度、W:width宽度
    # ======输出处理======
    # 重塑形状(忽略第1维),4维变3维
    # 调整输出out的形状,模型推理输出out是四维BCHW形式的,调整为三维CHW形式
    out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])
    # 对输入的数组(或图像)进行归一化处理,使其数值范围在指定的范围内
    cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)
    # 转置输出结果的维度
    result = out_new.transpose(1, 2, 0)
    
    # 显示转换后的图像
    cv2.imshow('Stylized Image', result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 原图如下:
      在这里插入图片描述
    • 效果图如下:
      在这里插入图片描述
;