OpenCv高阶(十二)——DNN风格迁移


前言

DNN(Deep Neural Network,深度神经网络)风格迁移是一种利用深度神经网络技术,将一张图像的风格(如色彩、笔触、纹理等)迁移到另一张图像(内容图像)上,使内容图像呈现出风格图像的风格,同时保留其自身内容的技术。

一、DNN风格迁移


DNN模块是 OpenCV 中专门用来实现 DNN(Deep Neural Networks,深度神经网络) 模块的相关功能,其作用是载入别的深度学习框架(如 TensorFlow、Caffe、Torch 等)中已经训练好的模型,然后用该模型完成预测等工作。 DNN模块的特点:
● 轻量: OpenCV 的深度学习模块只实现了模型推理功能,不涉及模型训练,这使得相关程序非常精简,加速了安装和编译过程。
● 外部依赖性低:重新实现一遍深度学习框架使得 DNN 模块对外部依赖性极低,极大地方便了深度学习应用的部署。
● 方便:在原有 OpenCV 开发程序的基础上,通过 DNN 模块可以非常方便地加入对神经网络推理的支持。
● 集成:若网络模型来自多个框架,如一个来自 TensorFlow,另外一个来自 Caffe,则 DNN 模块可以方便地对网络进行整合。
● 通用性:DNN 模块提供了统一的接口来操作网络模型,内部做的优化和加速适用于所有网络模型格式,支持多种设备和操作系统。
DNN 模块使用的主要函数及流程:
​​
在这里插入图片描述
​​
1、图像预处理的功能 将需要处理的图像转换成可以传入人工神经网络的数据形式。 DNN 模块中的函数 blobFromlmage 完成图像预处理,从原始图像构建一个符合人工神经网络输入格式的四维块。 它通过调整图像尺寸和裁图像、减均值、按比例因子缩放、交换 B 通道和R通道等可选操作完成对图像的预处理,得到符合人工神经网络输入的目标值。

效果展示:
使用不同的已训练好的模型可以得到不同的效果。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
2、DNN风格迁移模型
模型下载地址链接: https://github.com/jcjohnson/fast-neural-style/blob/master/models/download_style_transfer_models.sh
在这里插入图片描述

这里跳转网站速度会很慢,因为GitHub是国外网站。

二、DNN 风格迁移的使用

1、对图片做DNN风格迁移

(1)读取并显示即将做风格迁移的图片

import cv2
# 读取输入图像
image = cv2.imread('car.png')
# 显示输入图像
cv2.imshow('yuan tu', image)
cv2.waitKey(0)

(2)图片预处理

需要对图片做预处理,使神经网络能识别出图片。
函数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。· opencv BGR RGB
swapRB:表示在必要时交换通道的R通道和B通道。一般情况下使用的是RGB通道。而OpenCV通常采用的是BGR通道。
因此可以根据需要交换第1个和第3个通道。该值默认为 False。
crop:布尔值,如果为 True,则在调整大小后进行居中裁剪。
返回值:blob: 表示在经过缩放、裁剪、减均值后得到的符合人工神经网络输入的数据。该数据是一个四维数据,
布局通常使用N(表示batch size)、C(图像通道数,如RGB图像具有三个通道)、H(图像高度)、W(图像宽度)表示

(h, w) = image.shape[:2]  # 获取图像尺寸
blob = cv2.dnn.blobFromImage(image, 1, (w, h), (0, 0, 0), swapRB=False, crop=False)

(3)读取加载模型

加载模型net=cv2.dnn.readNet( model[, config[, framework]] )
各参数的含义如下:
model:神经网络的实际结构和功能,它定义了数据如何通过网络流动,如何进行训练,如何进行推理。
config:一组超参数和设置,帮助控制模型的行为,包括网络架构、训练过程、优化器等内容。
framework:DNN框架,可省略,DNN模块会自动推断框架种类。
net:返回值,返回网络模型对象。
支持的模型格式有Torch,TensorFlow,Caffe,DartNet,ONNX和Intel OpenVINO

model参数 | config参数 | framework参数 | 函数名称
*.caffemodel | *.prototxt | caffe | readNetFremoCaffe
*.pd | *.pbtxt | tensorflow | readNetFromTensorFlow
*.t7 | *.net | torch | readNetFromTorch
*.weight | *.cfg | darknet | readNetFromDarknet
*.bin | *.xml | dldt | readNetFromModelOptimizer
*.onnx | | onnx | readNetFromONNX

模型下载链接: https://cs.stanford.edu/people/jcjohns/fast-neural-style/models/eccv16/composition_vii.t7

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')

(4)网络输入

# 设置神经网络的输入
net.setInput(blob)
# 对输入图像进行前向传播,得到输出结果
out = net.forward()

(5)网络输出

# 重塑形状(忽略第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()

(6)完整代码

import cv2

image=cv2.imread('../data/man.png')

cv2.imshow('yuantu',image)

cv2.waitKey(0)

#__________________________图片预处理__________________________________
(h,w)=image.shape[:2]

blob= cv2.dnn.blobFromImage(image,1,(w,h),(0,0,0),swapRB=False,crop=False)


#__________________________加载模型__________________________________
net=cv2.dnn.readNet(r'../data/model/candy.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()

三、将DNN风格迁移应用到视频

import cv2

cap = cv2.VideoCapture('cxk.mp4')  #  0
net=cv2.dnn.readNetFromTorch(r'.\model\starry_night.t7')
if not cap.isOpened():  # 打开失败
    print("摄像头启动失败")
    exit()
while True:
    ret, frame = cap.read()  # 如果正确读取帧,ret为True
    if not ret:  # 读取失败,则退出循环
        print("不能读取摄像头")
        break
    # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 图像处理-转换为灰度图
    (h, w) = frame.shape[:2]
    blob = cv2.dnn.blobFromImage(frame, 1, (w, h), (0, 0, 0), swapRB=True, crop=False)
    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('result', result)
    key_pressed = cv2.waitKey(10)   #60
    if key_pressed == 27:  # 如果按下esc键,就退出循环
        break
cap.release()  # 释放捕获器
cv2.destroyAllWindows()  # 关闭图像窗口

同理,将视频改为摄像头就可以实时对摄像头读取的每一帧画面做DNN风格迁移。
效果展示:

请添加图片描述

总结

DNN风格迁移通过预训练网络的特征空间分离内容与风格,利用优化算法调和两者的统计特性,最终生成艺术化图像。这一方法结合了深度学习特征表达的强大能力与优化理论的灵活性,成为计算机视觉与艺术创作的桥梁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值