opencv计算机视觉--DNN模块实现风格迁移

1. DNN模块是什么?

OpenCV DNN(Deep Neural Networks)模块是一个用于深度神经网络推理的模块,它允许用户在OpenCV中加载和运行预训练的深度学习模型。主要特点:

  • 跨框架支持:支持TensorFlow、PyTorch、Caffe、DarkNet、ONNX等多种框架训练的模型

  • 硬件加速:支持CPU、GPU(CUDA、OpenCL)推理

  • 轻量级:无需安装完整的深度学习框架

  • 实时推理:针对计算机视觉任务优化,适合实时应用

2. 核心函数详解

2.1 cv2.dnn.blobFromImage() - 图像预处理

python 复制代码
blob = cv2.dnn.blobFromImage(
    image,          # 输入图像(BGR格式)
    scalefactor=1.0, # 像素值缩放因子(通常为1/255)
    size=(w, h),    # 输出blob的尺寸(模型要求的输入尺寸)
    mean=(0, 0, 0), # 各通道减去的均值(通常是训练时的均值)
    swapRB=True,    # 是否交换R和B通道(OpenCV用BGR,模型通常用RGB)
    crop=False      # 是否中心裁剪
)

参数详细说明:

参数 类型 默认值 说明
image ndarray - 输入图像,OpenCV读取的BGR格式图像
scalefactor float 1.0 像素值缩放系数: pixel = pixel × scalefactor 常用值:1/255.0(归一化到0-1)
size tuple - 输出blob的(width, height),必须是模型要求的输入尺寸
mean tuple/scalar (0,0,0) 各通道要减去的均值: pixel = pixel - mean 常用值:(104, 117, 123)(Caffe模型)或(0.485, 0.456, 0.406)(ImageNet均值)
swapRB bool False 是否交换R和B通道: True:BGR→RGB False:保持BGR
crop bool False 是否中心裁剪: True:调整大小后中心裁剪 False:直接resize

返回值:

  • blob:4D数组,形状为(1, C, H, W),其中:

    • 1:batch size(单张图像)

    • C:通道数(通常为3)

    • H:高度

    • W:宽度

2.2 cv2.dnn.readNet() - 加载模型

各参数的含义如下:

model: 神经网络的实际结构和功能。它定义了数据如何通过网络流动,如何进行训练,如何进行推理

config: 一组组参数和设置,帮助控制模型的行为,包括网络架构、训练过程、优化器等内容

framework: DNN框架,可省略。DNN模块会自动推断框架种类

net: 返回值,返回网络模型对象

支持的主要模型格式:

框架 模型文件 配置文件 专用函数
Caffe .caffemodel .prototxt readNetFromCaffe()
TensorFlow .pb .pbtxt readNetFromTensorflow()
PyTorch .t7.pth - readNetFromTorch()
Darknet .weights .cfg readNetFromDarknet()
ONNX .onnx - readNetFromONNX()
OpenVINO .xml .bin readNetFromModelOptimizer()

参数说明:

  • model:包含训练权重的文件

  • config:网络架构定义文件(对于某些框架)

  • framework:显式指定框架类型(通常可自动推断)

2.3 其他重要函数

python 复制代码
# 设置输入
net.setInput(blob, name="input")  # name可选,指定输入层名称

# 前向传播
output = net.forward(outputName=None)  # 输出指定层的结果

# 获取网络信息
layer_names = net.getLayerNames()  # 获取所有层名
unconnected_layers = net.getUnconnectedOutLayers()  # 获取输出层索引

3. 注意事项

  1. 通道顺序 :OpenCV默认BGR,许多模型期望RGB,注意swapRB参数

  2. 归一化:确保预处理与模型训练时一致

  3. 尺寸匹配:输入尺寸必须与模型要求一致

  4. 均值减法:如果模型训练时进行了均值减法,推理时也要做

  5. 输出解析:不同模型的输出格式不同,需要根据具体任务解析

DNN模块为在OpenCV中集成深度学习模型提供了统一接口,大大简化了深度学习模型的部署过程。

4.实际运用

1)对图片进行风格迁移

python 复制代码
import cv2

# 读取输入图像
image = cv2.imread('xiaomao.jpg')
image=cv2.resize(image,dsize=None,fx=0.5,fy=0.5)
# 显示输入图像
cv2.imshow('yuan', image)
cv2.waitKey(0)

# 图片预处理
(h, w) = image.shape[:2]  # 获取图像尺寸


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

net = cv2.dnn.readNet('model\\candy.t7')  # 得到一个用torch训练之后的星空模型

# 设置输入
net.setInput(blob)

# 对输入图像进行前向传播,得到输出结果
out = net.forward()

# 将输出结果转换为合适的格式
# out是四维的:B*C*H*W
# B: batch图像数量(通常为1),C: channels通道数,H: height高度,W: width宽度

# 输出处理
# 重塑形状(忽略第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('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

2)对视频或摄像头进行风格迁移

python 复制代码
import cv2

# 加载模型
net = cv2.dnn.readNet('model\\candy.t7')  # 加载风格迁移模型

# 打开视频文件或摄像头
# 如果是视频文件,使用:cv2.VideoCapture('your_video.mp4')
# 如果是摄像头,使用:cv2.VideoCapture(0)  # 0表示默认摄像头
cap = cv2.VideoCapture(0)  # 修改为你的视频文件路径


while True:
    # 读取视频帧
    ret, frame = cap.read()

    # 如果读取失败(视频结束),退出循环
    if not ret:
        print("视频结束或读取失败")
        break

    # 可选:调整帧大小(如果太大可以缩小)
    frame = cv2.resize(frame, None, fx=0.4, fy=0.4)

    # 获取当前帧的尺寸
    (h, w) = frame.shape[:2]

    # 预处理图像,创建blob
    blob = cv2.dnn.blobFromImage(
        frame,
        scalefactor=1.0,
        size=(w, h),
        mean=(0, 0, 0),
        swapRB=False,
        crop=False
    )

    # 设置输入并进行前向传播
    net.setInput(blob)
    out = net.forward()

    # 处理输出结果
    # 重塑形状:4维(B,C,H,W) -> 3维(C,H,W)
    out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])

    # 归一化
    cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)

    # 转置维度:(C,H,W) -> (H,W,C)
    result = out_new.transpose(1, 2, 0)

    # 或者只显示风格化后的帧
    cv2.imshow('shipin', result)

    # 可选:保存到输出视频
    # out.write(result)

    # 按'esc'键退出
    key = cv2.waitKey(30)
    if key == 27:  # 按下Esc键,退出循环
        break

# 释放资源
cap.release()
# out.release()  # 如果使用了VideoWriter,取消注释
cv2.destroyAllWindows()

5.延申

任务

将摄像头实时画面分割成四个方格,每个方格应用不同的艺术风格滤镜,最后拼接成一个完整画面展示出来。

(传入的图片缩放一下再处理,不然会卡顿)

python 复制代码
import cv2
import numpy as np

cap = cv2.VideoCapture(0)  # 0 表示默认摄像头

# 加载四种风格迁移模型
net1 = cv2.dnn.readNetFromTorch(r'model\starry_night.t7')  # 星夜
net2 = cv2.dnn.readNetFromTorch(r'model\the_scream.t7')  # 呐喊
net3 = cv2.dnn.readNetFromTorch(r'model\feathers.t7')  # 羽毛
net4 = cv2.dnn.readNetFromTorch(r'model\mosaic.t7')  # 马赛克


# 风格迁移处理函数(修正版)
def qianyi(frame,net):
    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


while True:
    ret, frame = cap.read()
    frame = cv2.resize(frame, dsize=None, fx=0.3, fy=0.3)  # 缩小到30%

    if not ret:
        print("不能读取摄像头")
        break

    (h, w) = frame.shape[:2]

    # 将画面分为四个区域
    zs = frame[:h // 2, 0:w // 2]  # 左上
    ys = frame[:h // 2, w // 2:]  # 右上
    zx = frame[h // 2:, :w // 2]  # 左下
    yx = frame[h // 2:, w // 2:]  # 右下

    # 分别对四个区域应用不同风格
    qianyi_zs = qianyi(zs, net1)  # 左上:星夜
    qianyi_ys = qianyi(ys, net2)  # 右上:呐喊
    qianyi_zx = qianyi(zx, net3)  # 左下:羽毛
    qianyi_yx = qianyi(yx, net4)  # 右下:马赛克

    # 拼接结果
    shang = np.hstack((qianyi_zs, qianyi_ys))  # 上半部分
    xia = np.hstack((qianyi_zx, qianyi_yx))  # 下半部分
    result = np.vstack((shang, xia))  # 完整结果

    cv2.imshow('result', result)

    key_pressed = cv2.waitKey(1)
    if key_pressed == 27:  # ESC键退出
        break

cap.release()
cv2.destroyAllWindows()
相关推荐
m0_706653233 小时前
用Python创建一个Discord聊天机器人
jvm·数据库·python
tlwlmy3 小时前
python excel图片批量导出
开发语言·python·excel
ValhallaCoder3 小时前
hot100-矩阵
数据结构·python·算法·矩阵
那年我七岁4 小时前
android ndk c++ 绘制图片方式
android·c++·python
Java后端的Ai之路4 小时前
【Python教程10】-开箱即用
android·开发语言·python
Faker66363aaa4 小时前
鲶鱼目标检测与识别:基于fovea_r50_fpn_gn-head-align模型的COCO数据集训练_1
人工智能·目标检测·计算机视觉
深蓝电商API4 小时前
异步爬虫中代理池的并发管理
开发语言·爬虫·python
B站计算机毕业设计超人4 小时前
计算机毕业设计PySpark+Hive+Django小红书评论情感分析 小红书笔记可视化 小红书舆情分析预测系统 大数据毕业设计(源码+LW+PPT+讲解)
大数据·人工智能·hive·爬虫·python·spark·课程设计
黄筱筱筱筱筱筱筱4 小时前
7.适合新手小白学习Python的异常处理(Exception)
java·前端·数据库·python