在计算机视觉领域,风格迁移是极具趣味性的应用方向之一------它能将普通图像/视频帧赋予梵高、蒙克等艺术大师的创作风格。本文将基于OpenCV的DNN模块,从零讲解如何实现静态图片的风格迁移,以及进阶的实时摄像头视频四宫格多风格迁移,同时整理了全量适配的风格模型清单,让你轻松玩转艺术与技术的结合。
一、核心原理与工具准备
1. 核心技术:OpenCV DNN模块
OpenCV的DNN(Deep Neural Networks)模块支持加载多种预训练深度学习模型(如Torch、TensorFlow、Caffe等),无需手动搭建复杂的神经网络,就能快速实现风格迁移推理。本次案例中,我们使用基于Torch框架训练的风格迁移模型(.t7格式),这类模型已提前完成风格特征的学习,只需传入图像数据即可完成风格迁移。
2. 环境与资源准备
• 开发环境:Python 3.x + OpenCV(需确保安装了dnn模块,建议安装opencv-contrib-python)
• 预训练模型:下载Torch格式的风格迁移模型(.t7),新建model文件夹存放模型文件,本文整理了全量常用模型清单,可直接下载使用。
• 测试素材:静态图片(如123.png)或电脑摄像头(实时视频用)。
安装OpenCV命令:
pip install opencv-contrib-python numpy
二、基础实现:静态图片风格迁移
先从最简单的静态图片风格迁移入手,理解核心流程:图像预处理→加载模型→推理计算→输出处理,所有风格模型均可直接替换到该案例中。
1. 完整代码实现
python
import cv2
# 1. 读取并显示原始图片
image = cv2.imread('123.png')
cv2.imshow('原始图片', image)
cv2.waitKey(0)
# 2. 图片预处理:构建神经网络输入Blob
(h, w) = image.shape[:2]
# blobFromImage:将图像转为DNN模块要求的四维(BCHW)输入格式
blob = cv2.dnn.blobFromImage(
image, # 输入图像
scalefactor=1, # 像素值缩放因子
size=(w, h), # 输出Blob的尺寸
mean=(0, 0, 0), # 通道均值(不减去均值)
swapRB=False, # OpenCV默认BGR,模型若为RGB需设为True
crop=False # 不裁剪
)
# 3. 加载预训练风格迁移模型(可替换为本文任意.t7模型)
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')
# 4. 模型推理:前向传播获取风格化结果
net.setInput(blob) # 设置网络输入
out = net.forward() # 前向传播计算
# 5. 输出结果处理
# 重塑维度:四维(BCHW)→三维(CHW)
out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])
# 归一化:将数值范围调整至0~1
cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)
# 维度转置:CHW→HWC(符合OpenCV图像显示格式)
result = out_new.transpose(1, 2, 0)
# 6. 显示并保存结果
cv2.imshow('风格迁移结果', result)
cv2.waitKey(0)
cv2.imwrite('style_result.png', result * 255) # 归一化后需乘以255还原像素值
cv2.destroyAllWindows()
2. 关键步骤解析
• Blob构建:cv2.dnn.blobFromImage是核心预处理函数,将普通HWC格式的图像转为DNN模型要求的NCHW(批量数-通道数-高度-宽度)格式,同时完成缩放、均值减法、通道交换等操作。
• 模型加载:cv2.dnn.readNetFromTorch专门加载Torch框架的.t7模型,不同框架的模型需使用对应函数(如Caffe用readNetFromCaffe)。
• 输出处理:模型输出是四维张量,需先重塑为三维,再通过归一化将数值约束在0~1范围,最后转置维度还原为OpenCV可显示的HWC格式。
三、进阶实战:实时视频四宫格多风格迁移
基于静态图片的思路,我们扩展到实时摄像头视频,实现四宫格分区域应用不同风格,让画面同时呈现多种艺术效果,代码中使用的模型可直接替换为本文清单中的任意风格。
1. 完整代码实现
python
import cv2
import numpy as np
# 1. 加载多个预训练风格迁移模型(可替换为本文任意.t7模型)
net1 = cv2.dnn.readNetFromTorch('model/starry_night.t7') # 星空风格
net2 = cv2.dnn.readNetFromTorch('model/the_scream.t7') # 呐喊风格
net3 = cv2.dnn.readNetFromTorch('model/feathers.t7') # 羽毛风格
net4 = cv2.dnn.readNetFromTorch('model/mosaic.t7') # 马赛克风格
# 2. 定义风格迁移处理函数
def style_transfer(frame, net):
"""
单帧图像风格迁移,适配所有.t7格式风格模型
:param frame: 输入帧(HWC格式)
:param net: 预训练风格模型
:return: 风格化后的帧
"""
h, w = frame.shape[:2]
# 构建Blob(注意swapRB=True:OpenCV BGR转RGB适配模型)
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))
return result
# 3. 初始化摄像头捕获
cap = cv2.VideoCapture(0) # 0表示默认摄像头
while True:
ret, frame = cap.read()
if not ret:
print("无法读取摄像头画面!")
break
# 镜像翻转+缩放:提升体验并降低计算量
frame = cv2.flip(frame, 1) # 水平镜像(符合人眼习惯)
frame = cv2.resize(frame, dsize=None, fx=0.3, fy=0.3) # 缩小为原尺寸30%
h, w = frame.shape[:2]
# 4. 分割画面为四个子区域
top_left = frame[:h//2, :w//2] # 左上
top_right = frame[:h//2, w//2:] # 右上
bottom_left = frame[h//2:, :w//2] # 左下
bottom_right = frame[h//2:, w//2:]# 右下
# 5. 各区域应用不同风格
tl_style = style_transfer(top_left, net1)
tr_style = style_transfer(top_right, net2)
bl_style = style_transfer(bottom_left, net3)
br_style = style_transfer(bottom_right, net4)
# 6. 拼接四宫格
top_row = np.hstack((tl_style, tr_style)) # 水平拼接上两行
bottom_row = np.hstack((bl_style, br_style))# 水平拼接下两行
final_result = np.vstack((top_row, bottom_row)) # 垂直拼接最终画面
# 7. 显示结果
cv2.imshow('实时四宫格风格迁移', final_result)
# 按ESC键退出(ASCII码27)
if cv2.waitKey(1) == 27:
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
2. 核心优化与扩展点
• 实时性优化:通过cv2.resize缩小画面尺寸,减少模型推理的计算量,避免卡顿;若仍卡顿,可进一步降低缩放比例(如fx=0.2)。
• 画面分割与拼接:利用numpy的hstack(水平拼接)和vstack(垂直拼接)实现四宫格,也可扩展为九宫格、二分屏等布局。
• 通道适配:实时视频处理中swapRB=True,因为多数预训练模型基于RGB通道训练,而OpenCV读取的帧是BGR格式,需交换通道匹配模型。
• 模型替换:代码中四个模型可任意替换为本文清单中的风格,只需修改模型文件路径,无需调整函数参数。
四、OpenCV DNN风格迁移全量预训练模型清单
所有模型均为.t7格式,完美适配OpenCV DNN模块,可直接放入代码同级的model文件夹使用,无需修改风格迁移函数,涵盖经典艺术风格、特色纹理风格,满足不同场景需求。
1. 经典艺术大师风格(高辨识度)
| 模型文件名 | 对应风格 / 作者 | 风格特点 | 适配场景 |
|---|---|---|---|
starry_night.t7 |
星空夜(梵高) | 蓝紫色调,星空漩涡纹理,艺术感强烈 | 风景、夜景、人像背景 |
the_scream.t7 |
呐喊(蒙克) | 扭曲线条 + 强烈色彩对比,视觉冲击感强 | 创意人像、抽象场景 |
van_gogh.t7 |
梵高通用风格 | 融合星空、麦田经典笔触,风格更百搭 | 所有通用场景 |
picasso.t7 |
毕加索(立体主义) | 几何分割画面,标志性立体主义风格 | 创意静物、人像 |
composition_vii.t7 |
第七交响曲(康定斯基) | 抽象几何 + 大胆色彩拼接,现代艺术感 | 创意设计、风景拼接 |
2. 热门特色纹理风格(高实用性)
| 模型文件名 | 风格名称 | 风格特点 | 适配场景 |
|---|---|---|---|
feathers.t7 |
羽毛纹理 | 轻透羽毛质感,细腻纹理叠加,画面柔和 | 人像、清新风景 |
feathers_soft.t7 |
柔羽风格 | 羽毛风格轻透版,纹理更淡,低饱和度 | 人像磨皮、唯美风景 |
mosaic.t7 |
基础马赛克 | 像素化块状拼接,抽象简约,纹理粗犷 | 创意遮挡、抽象场景 |
mosaic_art.t7 |
艺术马赛克 | 马赛克进阶版,块状纹理带渐变,更细腻 | 创意设计、静物 |
candy.t7 |
糖果风格 | 高饱和度糖果色,卡通磨砂质感,色彩明快 | 儿童照片、清新静物 |
la_muse.t7 |
缪斯风格 | 复古油画质感,暖色调为主,线条流畅 | 复古人像、欧式风景 |
udnie.t7 |
乌迪内风格 | 涂鸦式流畅线条,色彩渐变自然,抽象表现主义 | 创意人像、街头风景 |
wave.t7 |
梵高波浪风格 | 星空延伸风格,柔和波浪纹理,画面有韵律 | 水面、天空、风景 |
shipwreck.t7 |
海难(梵高) | 厚重油画笔触,大地色 + 蓝色调,氛围感强 | 户外风景、复古场景 |
rain_princess.t7 |
雨中公主 | 梦幻柔焦质感,粉紫蓝主色调,画面朦胧 | 女生人像、唯美夜景 |
scream_moderne.t7 |
现代版呐喊 | 经典呐喊简化版,线条简洁,色彩对比柔和 | 轻创意人像、抽象场景 |
模型使用与下载说明
-
直接替换:将模型文件放入model文件夹,修改代码中cv2.dnn.readNetFromTorch后的文件路径即可,如net = cv2.dnn.readNetFromTorch('model/candy.t7')。
-
效果优化:若部分风格显示偏暗/偏亮,可微调cv2.normalize归一化范围,或在blobFromImage中调整mean均值参数(如mean=(10,10,10))。
-
下载方式:所有模型均可通过OpenCV官方资源库、GitHub风格迁移开源仓库(如torch-style-transfer)下载,搜索「模型文件名+t7」即可,文件大小均在几十MB内,无需额外训练。
五、常见问题与解决方案
-
模型加载失败:检查模型路径是否正确(避免中文路径),确保.t7模型文件完整无损坏;相对路径报错可改用绝对路径(如C:/project/model/starry_night.t7)。
-
画面显示异常(全黑/全白):确认执行了cv2.normalize归一化步骤,输出结果需在0~1范围;转置维度时注意顺序为(1,2,0),匹配OpenCV的HWC格式。
-
实时视频卡顿:除缩小画面尺寸,还可降低摄像头分辨率(cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)),或更换轻量化模型(如candy.t7、feathers.t7)。
-
图像保存失真:归一化后数值范围为0~1,保存时需乘以255还原为0~255像素值,如cv2.imwrite('result.png', result * 255)。
-
四宫格拼接报错:确保四个子区域风格化后尺寸一致,若报错可在风格迁移函数中增加尺寸校验,避免维度不匹配。
六、总结与拓展
本文基于OpenCV DNN模块,从静态图片到实时视频,完整实现了风格迁移的核心流程,同时整理了全量适配的.t7格式风格模型清单,无需深度学习框架即可快速实现艺术风格迁移。OpenCV DNN模块的优势在于轻量化、易上手,适合快速部署和入门学习。
拓展方向:
• 批量图片处理:遍历文件夹,对多张图片自动应用指定风格迁移并批量保存,提升处理效率。
• 风格混合:调整不同风格模型的输出权重,将多种风格融合,实现个性化的艺术效果。
• 视频文件处理:将cv2.VideoCapture(0)改为读取视频文件(如cap = cv2.VideoCapture('test.mp4')),对视频逐帧处理并保存为新的风格化视频。
• 自定义布局:将四宫格扩展为九宫格、三分屏,或自定义区域大小,实现个性化的多风格拼接。
通过本文的案例和模型清单,你不仅能掌握OpenCV DNN模块的基础用法,还能发挥创意,结合不同艺术风格与计算机视觉,做出更多有趣的创意应用!







