前言相信很多接触计算机视觉的同学都听过风格迁移—— 这项技术能把一张名画的艺术风格 “移植” 到普通照片上让你的随手拍秒变世界名画同款画风。很多同学会觉得风格迁移需要搭建复杂的深度学习网络、准备 GPU 训练环境、处理海量数据集门槛很高。但其实我们只用 OpenCV 自带的DNN 深度神经网络模块无需安装 TensorFlow/PyTorchCPU 就能运行几十行代码就能实现高质量的图像风格迁移新手也能零门槛上手。先给大家看一下本文代码最终实现的效果左侧是我输入的氛围感人像原图右侧是经过抽象艺术风格迁移后的输出结果完美复刻了油画的笔触质感与色彩张力同时完整保留了人像的核心轮廓与特征本文就带大家从零实现基于 OpenCV DNN 的图像风格迁移包含完整可运行代码、核心 API 逐参详解、踩坑避坑指南、预训练模型资源看完就能直接跑出和上图一致的效果。一、核心原理简介我们本次使用的是快速神经风格迁移Fast Neural Style Transfer方案出自论文《Perceptual Losses for Real-Time Style Transfer and Super-Resolution》和传统的迭代优化风格迁移相比它有两大核心优势提前训练好针对特定风格的模型推理时只需一次前向传播速度极快CPU 也能毫秒级出结果无需复杂的深度学习框架OpenCV 的 DNN 模块可直接加载预训练模型环境配置极简。简单来说整个流程就是读取输入的内容图像做预处理适配神经网络输入格式加载对应风格的预训练模型把预处理后的图像输入模型执行前向传播得到风格化结果对模型输出的结果做后处理还原成可显示的图像格式。二、环境准备本文的方案环境配置极其简单仅需安装基础的 OpenCV 库即可# 安装opencv-python建议4.0及以上版本对DNN模块支持更完善 pip install opencv-python4.5.5.62Python 版本建议 3.7~3.10兼容性最佳运行环境无需 GPU普通家用电脑 CPU 即可流畅运行三、核心 API 详解本文代码核心用到了 OpenCV DNN 模块的两个核心 API这里先给大家讲透每个参数的含义避免后续踩坑。3.1 cv2.dnn.blobFromImage图像预处理函数这个函数的作用是把普通的 OpenCV 图像转换成神经网络能接受的输入格式四维 blob 块是深度学习推理前的核心预处理步骤。函数原型blob cv2.dnn.blobFromImage( image, scalefactorNone, sizeNone, meanNone, swapRBNone, cropNone )各参数详解参数名作用说明本文取值image输入的原始图像cv2.imread 读取的结果人像原图scalefactor像素值缩放因子每个像素值会乘以该系数默认值为 11不缩放像素值size输出 blob 的宽高对应神经网络要求的输入尺寸(w, h) 和原图尺寸一致mean每个通道要减去的均值用于消除光照影响格式为 (B,G,R)(0, 0, 0) 不做均值减法swapRB是否交换 R 通道和 B 通道。OpenCV 默认是 BGR 通道顺序很多模型训练用的是 RGB需通过该参数适配False 不交换通道crop调整尺寸后是否居中裁剪False 不裁剪保持原图比例返回值blob是一个四维张量格式为N(批次)×C(通道数)×H(高度)×W(宽度)这是深度学习框架通用的输入格式。3.2 cv2.dnn.readNetFromTorchTorch 模型加载函数我们使用的预训练风格模型是 Torch 框架的.t7格式通过这个函数可以直接加载模型无需安装 Torch/PyTorch 环境。函数原型net cv2.dnn.readNetFromTorch(modelPath)参数modelPath预训练模型.t7文件的路径返回值net加载完成的神经网络模型对象后续可直接用于推理除此之外OpenCV DNN 模块还支持 TensorFlow、Caffe、ONNX、Darknet 等几乎所有主流框架的模型兼容性极强大家后续可以自行拓展。四、完整代码逐段解析下面我们把完整代码拆分成 6 个模块逐行讲解每一步的作用大家可以跟着一步步写也可以直接复制完整代码运行就能跑出和前文一致的效果。4.1 库导入与图像读取首先导入 OpenCV 库读取我们要风格化的内容图像并显示原图确认图像读取正常。import cv2 # 读取输入图像内容图这里替换成你自己的图片路径 image cv2.imread(test_man.png) # 显示输入的原图 cv2.imshow(yuan tu, image) # 等待按键按下后再执行后续代码0表示无限等待 cv2.waitKey(0)⚠️ 踩坑提醒如果cv2.imread返回 None大概率是图像路径错误、文件名拼写错误或者路径包含中文建议优先使用英文绝对路径。4.2 图像预处理生成神经网络输入 blob获取图像尺寸通过cv2.dnn.blobFromImage把原图转换成神经网络接受的输入格式。-----------图片预处理------------------- # 获取图像的高度h和宽度w (h, w) image.shape[:2] # 生成神经网络输入的四维blob blob cv2.dnn.blobFromImage( image, scalefactor1, size(w, h), mean(0, 0, 0), swapRBFalse, cropFalse )这里我们保持了和原图一致的尺寸无需固定输入大小预训练模型支持任意尺寸的图像输入适配性极强。4.3 预训练模型加载加载我们提前下载好的风格迁移预训练模型本文提供了 6 种经典艺术风格的模型大家可以按需切换。本次展示的效果使用的是康定斯基《Composition VII》抽象艺术风格模型。加载模型 # 加载预训练的风格迁移模型本次效果使用的抽象艺术风格 netcv2.dnn.readNetFromTorch(r.\model\composition_vii.t7) # 其他风格模型取消注释即可切换 # netcv2.dnn.readNetFromTorch(r.\model\la_muse.t7) # 缪斯艺术风格 # netcv2.dnn.readNetFromTorch(r.\model\starry_night.t7) # 梵高星空风格 # netcv2.dnn.readNetFromTorch(r.\model\candy.t7) # 糖果色彩风格 # netcv2.dnn.readNetFromTorch(r.\model\the_scream.t7) # 呐喊风格 # netcv2.dnn.readNetFromTorch(r.\model\udnie.t7) # 抽象涂鸦风格⚠️ 路径提醒Windows 系统路径建议加r前缀避免反斜杠转义问题建议在项目根目录新建model文件夹把所有.t7模型文件放进去路径对应即可。4.4 模型推理前向传播把预处理好的 blob 输入模型执行前向传播得到风格化后的输出结果。# 设置神经网络的输入 net.setInput(blob) # 执行前向传播得到模型输出结果 out net.forward()这里的out是一个四维张量格式为1×3×H×W分别对应批次、通道数、高度、宽度无法直接用 OpenCV 显示需要做后处理。4.5 推理结果后处理这一步是新手最容易踩坑的地方我们需要把模型输出的四维张量还原成 OpenCV 能显示的图像格式分为 3 步# 输出处理 # 步骤14维降3维忽略批次维度把BCHW格式转为CHW格式 out_new out.reshape(out.shape[1], out.shape[2], out.shape[3]) # 步骤2归一化处理把像素值缩放到0-1之间适配cv2.imshow的float图像显示要求 cv2.normalize(out_new, out_new, norm_typecv2.NORM_MINMAX) # 步骤3维度转置把CHW通道×高度×宽度转为HWC高度×宽度×通道这是OpenCV要求的图像格式 result out_new.transpose(1, 2, 0)⚠️ 关键说明OpenCV 的cv2.imshow显示图像要求格式必须是H×W×C而模型输出是C×H×W必须通过transpose转置维度否则会报错或显示异常模型输出的像素值不是 0-255 的整数需要通过normalize缩放到 0-1 之间才能正常显示。4.6 结果显示与资源释放最后显示风格化后的图像释放所有窗口资源。# 显示风格转换后的图像 cv2.imshow(Stylized Image, result) # 等待按键按下 cv2.waitKey(0) # 释放所有OpenCV窗口 cv2.destroyAllWindows()五、完整可直接运行代码这里给大家整理了无注释精简版大家可以直接复制运行替换图片和模型路径即可import cv2 # 1. 读取输入图像 image cv2.imread(test_man.png) cv2.imshow(yuan tu, image) cv2.waitKey(0) # 2. 图片预处理 (h, w) image.shape[:2] blob cv2.dnn.blobFromImage(image, scalefactor1, size(w, h), mean(0, 0, 0), swapRBFalse, cropFalse) # 3. 加载预训练模型 netcv2.dnn.readNetFromTorch(r.\model\composition_vii.t7) # 4. 模型推理 net.setInput(blob) out net.forward() # 5. 输出结果后处理 out_new out.reshape(out.shape[1], out.shape[2], out.shape[3]) cv2.normalize(out_new, out_new, norm_typecv2.NORM_MINMAX) result out_new.transpose(1, 2, 0) # 6. 显示结果 cv2.imshow(Stylized Image, result) cv2.waitKey(0) cv2.destroyAllWindows()六、效果细节说明本次我使用的是康定斯基的《Composition VII》抽象艺术风格模型针对人像照片做风格迁移最终效果有两个核心亮点风格还原度高完美复刻了原作的色彩碰撞、几何线条和油画笔触质感整体艺术氛围拉满和原作的艺术风格高度统一内容保留完整人像的五官轮廓、动作姿态、光影层次都完整保留没有因为风格迁移出现内容失真、五官错位的问题实现了风格与内容的平衡。大家可以根据自己的图片内容选择不同的风格模型人像照片推荐使用 la_muse、composition_vii 风格风景照片推荐使用 starry_night、candy 风格街拍照片推荐使用 udnie、the_scream 风格。七、预训练模型下载本文用到的 6 种经典风格预训练模型均来自官方开源项目大家可以通过以下链接下载官方项目地址https://github.com/jcjohnson/fast-neural-style模型直链下载la_muse.t7https://cs.stanford.edu/people/jcjohns/fast-neural-style/models/la_muse.t7starry_night.t7https://cs.stanford.edu/people/jcjohns/fast-neural-style/models/starry_night.t7candy.t7https://cs.stanford.edu/people/jcjohns/fast-neural-style/models/candy.t7the_scream.t7https://cs.stanford.edu/people/jcjohns/fast-neural-style/models/the_scream.t7udnie.t7https://cs.stanford.edu/people/jcjohns/fast-neural-style/models/udnie.t7composition_vii.t7https://cs.stanford.edu/people/jcjohns/fast-neural-style/models/composition_vii.t7下载完成后把所有.t7文件放到项目的model文件夹下即可。八、常见踩坑与解决方案问题 1图像读取失败imread 返回 None原因路径包含中文、文件名拼写错误、相对路径错误解决方案使用英文绝对路径比如rC:\project\test_man.png确保文件存在问题 2模型加载失败报错 “Cant open model file”原因模型路径错误或者模型文件下载不完整解决方案检查路径拼写重新下载模型文件确保文件大小正常问题 3imshow 显示黑屏 / 全白 / 异常图像原因 1维度没有转置CHW 没有转为 HWC解决方案必须执行transpose(1, 2, 0)转换维度原因 2像素值没有归一化超出 0-1 范围解决方案用cv2.NORM_MINMAX把像素值缩放到 0-1 之间问题 4运行速度慢卡顿原因默认使用 CPU 推理大尺寸图像速度较慢解决方案缩小输入图像尺寸比如把 size 设为 (640, 480)开启 OpenCL 加速添加代码net.setPreferableTarget(cv2.dnn.DNN_TARGET_OPENCL)九、拓展延伸批量处理图像可以通过 os 模块遍历文件夹批量处理文件夹内的所有图片自动保存风格化后的结果视频风格迁移通过 cv2.VideoCapture 读取视频逐帧做风格迁移再写入视频文件实现视频画风转换实时摄像头风格迁移调用电脑摄像头实时处理每一帧画面实现实时滤镜效果更多风格模型可以自己训练专属风格的模型导出为 t7/onnx 格式用本文的代码直接加载使用。总结本文带大家用几十行 Python 代码基于 OpenCV DNN 模块实现了高质量的图像风格迁移无需复杂的深度学习环境CPU 就能运行新手也能零门槛上手最终实现的人像风格迁移效果也非常惊艳。OpenCV 的 DNN 模块给我们提供了极其便捷的深度学习推理方案无需关注复杂的网络结构只需做好预处理和后处理就能快速落地深度学习应用非常适合计算机视觉入门和快速项目开发。如果本文对你有帮助欢迎点赞、收藏、评论有任何问题都可以在评论区留言我会一一解答