计算机视觉(opencv)实战二十九——图像风格迁移


OpenCV DNN 模块实现图像风格迁移:原理与代码详解

在计算机视觉中,图像风格迁移(Neural Style Transfer)是一项非常有趣的应用。它可以将一幅图像的风格迁移到另一幅图像上,比如把一张人脸图像转换成梵高的《星空》风格。本篇文章将通过 OpenCV 的 dnn 模块,结合预训练的 PyTorch 模型,实现一个简易的风格迁移程序。


1. 环境准备与图像读取

原图和结果:

首先,我们需要安装 OpenCV,并加载一张输入图像作为测试对象。

复制代码
import cv2

# 获取输入图像
image = cv2.imread('face1.jpg')  # 读取本地图像
# 如果需要使用摄像头实时输入,可以改为:cap = cv2.VideoCapture(0)

# 显示原始图像
cv2.imshow('yuan tu', image)
cv2.waitKey(0)

要点:

  • cv2.imread() 用于读取本地图像,返回一个 NumPy 数组。

  • cv2.imshow() 可以显示图像,cv2.waitKey(0) 表示无限等待用户按键,否则窗口立即关闭。


2. 图像预处理:blobFromImage

在将图像输入到神经网络之前,我们需要将其转化为网络所需的输入格式。OpenCV 提供了 cv2.dnn.blobFromImage 函数,帮助我们完成这一过程。

复制代码
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 1, (w, h), (0, 0, 0), swapRB=False, crop=False)

参数详解

  • image:输入图像,必须是 NumPy 数组。

  • scalefactor:缩放因子,对像素值进行乘法缩放,默认 1 表示不缩放。

  • size:调整图像尺寸,必须与模型训练时的输入大小一致。

  • mean :通道均值,用于减去图像的平均值以进行归一化。设置为 (0,0,0) 表示不做均值减法。

  • swapRB:是否交换 R 和 B 通道。因为 OpenCV 默认是 BGR 通道,而许多深度学习模型训练时采用的是 RGB。

  • crop:是否在缩放后裁剪图像,通常设为 False。

最终返回的 blob 是一个 四维张量 ,格式为 NCHW

  • N:批量大小(batch size)

  • C:通道数(通常 3)

  • H:高度

  • W:宽度

参数名 类型 说明 默认值
image numpy.ndarray 输入图像,支持单张图像或多张图像列表。 必填
scalefactor float 缩放因子,将图像像素值缩放到神经网络所需范围,最终结果是 像素值 * scalefactor 1.0
size (width, height) 输出图像的大小(宽,高)。必须与模型训练时的输入尺寸匹配,否则可能导致推理失败或效果不佳。 不缩放
mean (meanR, meanG, meanB) 从每个通道减去的均值,用于归一化。可帮助消除光照影响。 (0, 0, 0)
swapRB bool 是否交换 R 和 B 通道。OpenCV 默认图像通道为 BGR,如果模型训练时使用 RGB,则需设为 True False
crop bool 是否在调整大小后居中裁剪图像。如果设为 False,直接按比例缩放到目标尺寸。 False
ddepth int 输出数据的深度,常用 cv2.CV_32F(32 位浮点)。 CV_32F

3. 加载预训练神经网络

接下来,我们需要加载一个预训练的神经网络模型。OpenCV 提供了 cv2.dnn.readNet,支持多种主流深度学习框架。

复制代码
# 加载模型
net = cv2.dnn.readNet(r"model\starry_night.t7")

参数说明

  • model:模型文件,包含神经网络的权重和计算图。

  • config:可选配置文件,定义网络架构。

  • framework:可选参数,指定模型的框架(如 caffe、tensorflow、onnx 等),不指定时 OpenCV 会自动推断。

模型类型 model 文件 config 文件 读取函数
Caffe *.caffemodel *.prototxt readNetFromCaffe
TensorFlow *.pb *.pbtxt readNetFromTensorFlow
Torch *.t7 / *.net readNetFromTorch
Darknet *.weights *.cfg readNetFromDarknet
OpenVINO *.bin *.xml readNetFromModelOptimizer
ONNX *.onnx readNetFromONNX

这里使用的是一个基于 Torch 训练的风格迁移模型 starry_night.t7,它能将输入图像转换为梵高星空的风格。


4. 前向传播与结果计算

有了模型和输入数据,我们就可以进行前向推理:

复制代码
# 设置输入
net.setInput(blob)
# 前向传播
out = net.forward()

此时 out 是一个四维张量,形状为 (B, C, H, W)

为了便于显示,我们需要对其进行 reshape、归一化和转置:

复制代码
# 调整形状,去掉 batch 维度
out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])

# 归一化到 0~1 或 0~255 范围
cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)

# 转置回 HWC 格式(OpenCV 图像格式)
result = out_new.transpose(1, 2, 0)

5. 显示风格迁移后的图像

最后,将处理好的图像显示出来:

复制代码
cv2.imshow('Stylized Image', result)
cv2.waitKey(0)

运行后,你将看到一幅带有梵高星空风格的图像。


6. 注意事项与优化建议

  1. 图像尺寸 :预处理时的 (w, h) 应与模型输入尺寸一致,否则可能失真。

  2. 归一化处理 :有些模型要求像素值范围在 [-1,1],需要调整 scalefactormean

  3. 性能优化 :若处理视频流,可以把 cv2.imshow() 放在循环中,实时显示风格化结果。

  4. GPU 加速 :可以用 net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) 开启 GPU 推理,速度会提升显著。


总结

本文通过 OpenCV 的 dnn 模块实现了一个简易的风格迁移程序,完整流程包括:

  1. 读取输入图像

  2. 使用 blobFromImage 进行预处理

  3. 加载预训练模型

  4. 前向推理得到风格化结果

  5. 归一化与维度变换

  6. 显示结果图像

这种方法可以快速实现艺术风格迁移,同时可以推广到目标检测、人脸识别等其他深度学习任务。

相关推荐
DisonTangor1 分钟前
阿里开源Qwen3-Omni-30B-A3B三剑客——Instruct、Thinking 和 Captioner
人工智能·语言模型·开源·aigc
独孤--蝴蝶2 分钟前
AI人工智能-机器学习-第一周(小白)
人工智能·机器学习
西柚小萌新4 分钟前
【深入浅出PyTorch】--上采样+下采样
人工智能·pytorch·python
丁学文武31 分钟前
大语言模型(LLM)是“预制菜”? 从应用到底层原理,在到中央厨房的深度解析
人工智能·语言模型·自然语言处理·大语言模型·大模型应用·预制菜
fie888936 分钟前
基于MATLAB的声呐图像特征提取与显示
开发语言·人工智能
文火冰糖的硅基工坊2 小时前
[嵌入式系统-100]:常见的IoT(物联网)开发板
人工智能·物联网·架构
刘晓倩2 小时前
实战任务二:用扣子空间通过任务提示词制作精美PPT
人工智能
却道天凉_好个秋2 小时前
OpenCV(七):BGR
opencv·计算机视觉
shut up2 小时前
LangChain - 如何使用阿里云百炼平台的Qwen-plus模型构建一个桌面文件查询AI助手 - 超详细
人工智能·python·langchain·智能体
Hy行者勇哥2 小时前
公司全场景运营中 PPT 的类型、功能与作用详解
大数据·人工智能