自学内容网 自学内容网

《深度学习》OpenCV 风格迁移、DNN模块 案例解析及实现

目录

一、风格迁移

1、什么是风格迁移

2、步骤

1)训练

2)迁移

二、DNN模块

1、什么是DNN模块

2、DNN模块特点

1)轻量

2)外部依赖性低

3)方便

4)集成

5)通用性

3、流程图

4、图像预处理功能

三、案例实现

1、定义自动缩放图片函数

2、图像预处理函数解析

1)参数解析:

• image (ndarray):输入图像

• scalefactor (float):图像缩放因子

• size (tuple):目标尺寸(宽度, 高度)

• mean (tuple):归一化图像数据

• swapRB (bool): 是否交换红蓝通道

• crop (bool):是否裁剪图像

• ddepth (int, 可选参数):目标图像的深度

2)返回值

3、图像预处理

调试模式:

4、关于cv2.dnn.readNet和cv2.dnn.readNetFromTorch

1)cv2.dnn.readNet

2)cv2.dnn.readNet参数

3)cv2.dnn.readNetFromTorch

4)参数

5、加载深度学习模型

1)模型文件

2)加载模型

6、图像导入神经网络

调试状态:

7、输出处理

展示结果:

8、也可以自由更换图片以及训练好的风格模型

9、完整代码


一、风格迁移

1、什么是风格迁移

        风格迁移是一种计算机视觉技术,通过将一幅图像的风格与另一幅图像的内容结合,生成一个新的图像。

        在OpenCV中,风格迁移通常使用神经网络来实现。

2、步骤

        1)训练

                首先,使用一幅参考图像作为“风格图像”和一幅目标图像作为“内容图像”,训练一个神经网络模型。训练过程中,网络学习如何将内容图像的内容与风格图像的风格进行组合。

        2)迁移

                一旦模型训练完成,就可以使用该模型将任意图像的内容与风格进行迁移。在迁移过程中,网络会将输入图像的内容与风格图像的风格进行匹配,并生成一个新的图像,该图像具有输入图像的内容和风格图像的风格。

二、DNN模块

1、什么是DNN模块

        DNN模块是 OpenCV 中专门用来实现 DNN(Deep Neural Networks,深度神经网络) 模块的相关功能,其作用是载入别的深度学习框架(如 TensorFlow、Caffe、Torch 等)中已经训练好的模型,然后用该模型完成预测等工作。

2、DNN模块特点

        1)轻量

                 OpenCV 的深度学习模块只实现了模型推理功能,不涉及模型训练,这使得相关程序非常精简,加速了安装和编译过程。

        2)外部依赖性低

                重新实现一遍深度学习框架使得 DNN 模块对外部依赖性极低,极大地方便了深度学习应用的部署。

        3)方便

                在原有 OpenCV 开发程序的基础上,通过 DNN 模块可以非常方便地加入对神经网络推理的支持。

         4)集成

                若网络模型来自多个框架,如一个来自 TensorFlow,另外一个来自 Caffe,则 DNN 模块可以方便地对网络进行整合。

         5)通用性

                DNN 模块提供了统一的接口来操作网络模型,内部做的优化和加速适用于所有网络模型格式,支持多种设备和操作系统。

3、流程图

4、图像预处理功能

        将需要处理的图像转换成可以传入人工神经网络的数据形式。 DNN 模块中的函数 blobFromlmage 完成图像预处理,从原始图像构建一个符合人工神经网络输入格式的四维块。 它通过调整图像尺寸和裁图像、减均值、按比例因子缩放、交换 B 通道和R通道等可选操作完成对图像的预处理,得到符合人工神经网络输入的目标值。

三、案例实现

1、定义自动缩放图片函数

import cv2
def resize(image,width=None,height=None ,inter=cv2.INTER_AREA):  # 输入参数为图像、可选宽度、可选高度、插值方式默认为cv2.INTER_AREA,即面积插值
    dim = None   # 存储计算后的目标尺寸w、h
    (h,w) = image.shape[:2]  # 返回输入图像高宽
    if width is None and height is None:   # 判断是否指定了宽和高大小,如果没有指定则返回原图
        return image
    if width is None:   # 判断如果没有指定宽度大小,则表示指定了高度大小,那么运行内部代码
        r = height/float(h)   # 指定高度与原图高度的比值
        dim = (int(w*r),height)   # 宽度乘以比值得到新的宽度,此处得到新的宽高
    else:  # 此处表示为width不是None,即指定了宽度,与上述方法一致,计算比值
        r = width/float(w)
        dim = (width,int(h*r))
    resized = cv2.resize(image,dim,interpolation=inter)     # 指定图像大小为上述的dim,inter默认为cV2.INTER_AREA,即面积插值,适用于缩放图像。
    return resized

        如果输入原图尺寸太大,可以直接调用这个函数来缩放图片,手动指定图像的宽度或高度,函数自动生成缩放后图片的高度或宽度。

2、图像预处理函数解析

cv2.dnn.blobFromImage(image, scalefactor, size, mean, swapRB=False, crop=False, ddepth=CV_32F)
        1)参数解析:
                • image (ndarray):输入图像

                     通常是一个通过cv2.imread读取的BGR图像。

                • scalefactor (float):图像缩放因子

                     这个值决定了图像在送入模型之前需要被缩放的程度。例如,如果设置为1.0,则图像保持原尺寸;如果设置为0.5,则图像的高度和宽度都会减半。

                • size (tuple):目标尺寸(宽度, 高度)

                     这个参数指定了图像在送入模型之前应该被调整到的尺寸。如果设置为(0, 0),则图像不会被调整尺寸,而是保持原样(但仍然会被缩放scalefactor指定的倍数)。

                • mean (tuple):归一化图像数据

                     从每个通道减去的均值。这个参数通常用于归一化图像数据,以匹配模型训练时使用的预处理步骤。它是一个包含三个元素的元组,分别对应B、G、R通道的均值。如果模型训练时没有使用均值减法,可以设置为(0, 0, 0)

                • swapRB (bool): 是否交换红蓝通道

                     是否交换红色和蓝色通道,即1通道和3通道交换,由于OpenCV默认使用BGR格式,而大多数深度学习框架(如PyTorch和TensorFlow)使用RGB格式,因此通常需要将B和R通道交换。如果设置为True,则会自动交换红色和蓝色通道。

                • crop (bool):是否裁剪图像

                     如果设置为True,并且size参数指定了一个非零尺寸,则图像会被裁剪到指定的尺寸。裁剪是通过从图像中心裁剪出一个矩形区域来实现的,该矩形区域的尺寸等于size指定的尺寸,并且尽可能保持图像的纵横比。如果设置为False,则图像会被调整(缩放和/或填充)到指定的尺寸,而不会裁剪

                • ddepth (int, 可选参数):目标图像的深度

                     这个参数在OpenCV的某些版本中可能不存在或不被使用。它通常设置为cv2.CV_32F(即32位浮点数),以确保图像数据以浮点数的形式传递给模型。然而,在最新版本的OpenCV中,这个参数可能已经被移除或不再是必需的,因为函数内部可能已经默认处理了图像数据的类型转换。

        2)返回值

                表示在经过缩放、裁剪、减均值后得到的符合人工神经网络输入的数。该数据是一个四维数据,布局通常使用N(表示batch size为批量大小)、C(图像通道数,如RGB图像具有三个通道)、H(图像高度)、W(图像宽度)表示

3、图像预处理

# 读取鑰入图像
a = cv2.imread('huanghelou.png')
image = resize(a,400)
# 显示输入图像
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)  # 将原始图像构建成神经网络可识别的格式,四维块
        调试模式:

4、关于cv2.dnn.readNet和cv2.dnn.readNetFromTorch

        1)cv2.dnn.readNet

                是一个更通用的函数,主要用于加载 Caffe、TensorFlow(通过中间转换为 .pb 文件或冻结图)、ONNX 等格式的深度学习模型。

        2)cv2.dnn.readNet参数

                model:参数指定模型架构文件的路径。

                config(可选):指定模型权重文件的路径。然而,对于某些格式(如 ONNX 和冻结的 TensorFlow.pb文件),权重和架构通常已经包含在同一个文件中,因此不需要config参数。

        3)cv2.dnn.readNetFromTorch

                是一个专门用于加载 Torch7(旧版 Torch)深度学习模型的函数。

        4)参数

                必需参数:模型文件的路径(通常是 .t7 扩展名),不需要额外的 config 参数,因为 Torch7 模型文件通常同时包含架构和权重信息。

5、加载深度学习模型

        1)模型文件

                模型文件皆是从网上下载的

        2)加载模型
net = cv2.dnn.readNet(r'model\starry_night.t7')   # 得到一个PyTorch训练之后的梵高的星空模型
# 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')

6、图像导入神经网络

# 设置神经网络的输入
net.setInput(blob)
# 对输入图像进行前向传播,得到输出结果
out = net.forward()
# out是四维的:B*C*H*W
        调试状态:

7、输出处理

# 重塑形状(忽略第1维),4维变3维
out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])
cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)  # 对输入数组out_new进行归一化处理,处理完的数组命名为out_new,可以手动设置归一化的值的范围,写None话则自动选择范围,cv2.NORM_MINMAX表示归一化类型为最小值到最大值归一化,未指出则使用0和255或者-1和1
result = out_new.transpose(1,2,0)  # 对多维数组进行转置,对于图像数据,意味着交换维度
cv2.imshow('Stylized Image',result)
cv2.waitKey(0)
cv2.destroyAllWindows()
        展示结果:

8、也可以自由更换图片以及训练好的风格模型

        可私信联系转化几个模型。

        (图片来源网络,如有侵权,敬请联系删除)

9、完整代码

import cv2
# 读取鑰入图像
image = cv2.imread('huanghelou.png')
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')   # 得到一个PyTorch训练之后的星空模型
# 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_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()


原文地址:https://blog.csdn.net/qq_64603703/article/details/142899237

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!