目录

一、 DNN 模块理论基础

1.1 DNN 模块是什么

1.2 DNN 模块的特点

1.3 DNN 模块使用的主要函数及流程

二、实操步骤:代码实现

2.1 导入库与读取图像

2.2 图像预处理(关键步骤)

2.3 加载模型与前向传播

2.4 输出结果处理

2.5 显示与保存结果

三、常见问题解决

四、总结与拓展

4.1 总结

4.2 拓展


本文基于 OpenCV 的 DNN 模块,结合理论知识与实际代码,带大家一步步完成图像风格迁移。


一、 DNN 模块理论基础

1.1 DNN 模块是什么

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

1.2 DNN 模块的特点

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

1.3 DNN 模块使用的主要函数及流程

DNN 模块使用主要遵循以下流程:

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

模型导入:使用cv.dnn.readNet函数导入预训练好的模型。

设置网络输入:调用net.setInput方法,将预处理后的图像数据设置为网络的输入。

网络计算:通过net.forward方法进行网络计算,得到最终的结果。


二、实操步骤:代码实现

2.1 导入库与读取图像

首先导入 OpenCV 库,读取待处理的内容图像(如Mona Lisa.png),并显示原始图像以便对比。

import cv2

# 读取输入图像(需确保图像路径正确,可使用相对路径或绝对路径)
image = cv2.imread('Mona Lisa.png')
# 显示原始图像,等待用户按键后关闭窗口
cv2.imshow('原始图像', image)
cv2.waitKey(0)

2.2 图像预处理(关键步骤)

根据 DNN 模块对输入的要求,模型输入需为 “四维块(B×C×H×W)”,通过cv2.dnn.blobFromImage()函数完成转换。

# 获取图像原始宽高(后续保持输出尺寸与输入一致)
(h, w) = image.shape[:2]

# 图像预处理:转换为模型可接受的四维格式
# 参数说明:
# image:输入图像;1:像素缩放因子(不缩放);(w, h):输出图像尺寸;
# (0, 0, 0):通道均值(不减去均值);False:不交换B/R通道;False:不裁剪
blob = cv2.dnn.blobFromImage(image, 1, (w, h), (0, 0, 0), False, False)

2.3 加载模型与前向传播

导入预训练模型,再将预处理后的blob传入模型,执行前向传播得到结果。

# 加载Torch预训练风格模型(以星空风格为例,需确保模型路径正确)
net = cv2.dnn.readNet(r"model\starry_night.t7")

# 设置模型输入
net.setInput(blob)

# 前向传播:获取模型输出的风格迁移结果
out = net.forward()

2.4 输出结果处理

模型输出out为四维数据(B×C×H×W),需转换为三维图像格式(H×W×C)才能正常显示。

# 1. 重塑维度:忽略batch维度(B=1),从4维转为3维(C×H×W)
out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])

# 2. 归一化:将像素值映射到0-1范围,避免显示异常
cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)

# 3. 调整通道顺序:从(C×H×W)转为(H×W×C),符合OpenCV显示格式
result = out_new.transpose(1, 2, 0)

2.5 显示与保存结果

查看风格迁移效果,若需留存结果可保存图像。

# 显示风格迁移后的图像
cv2.imshow('风格迁移结果', result)
cv2.waitKey(0)

# (可选)保存结果图像(乘以255是将0-1范围转回0-255像素范围)
cv2.imwrite('风格迁移结果.png', result * 255)

# 关闭所有窗口,释放资源
cv2.destroyAllWindows()


三、常见问题解决

问题现象 可能原因 解决方法
图像读取失败(无原始图像窗口) 图像路径错误;图像文件损坏 1. 使用绝对路径(如C:\Users\XXX\Mona Lisa.png);2. 确认图像格式为 PNG/JPG 且文件完好
模型加载报错(提示 “无法读取模型”) 模型路径错误;模型文件不完整 1. 核对模型路径(如model\starry_night.t7是否存在);2. 从可靠来源(如 GitHub)重新下载模型
输出图像全黑 / 全白 归一化参数错误;通道顺序调整错误 1. 确认cv2.normalizenorm_typecv2.NORM_MINMAX;2. 检查transpose顺序是否为(1,2,0)

四、总结与拓展

4.1 总结

本次实操严格遵循 DNN 模块 “预处理→模型导入→推理→结果处理” 的流程,核心是理解 “模型输入格式要求” 与 “图像维度转换逻辑”,这是保证风格迁移成功的关键。

4.2 拓展

更换风格:替换cv2.dnn.readNet()中的模型路径,可尝试向日葵、睡莲等其他风格的.t7模型;

优化图像:预处理前可加入 “图像平滑处理” 的高斯滤波(cv2.GaussianBlur()),减少原始图像噪声对结果的影响。

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务

更多推荐