基于 OpenCV 的摄像头四格实时风格迁移实现

一、项目介绍

1 实现效果

运行程序后,调用电脑默认摄像头,实时采集画面并分割为左上、右上、左下、右下四个区域,每个区域独立应用不同的艺术风格迁移模型(星月夜、缪斯、海浪、马赛克),最终拼接为完整画面实时展示,按下 Esc 键即可退出程序。

2.预训练风格模型准备

本文使用的是 OpenCV dnn 模块兼容的Torch 格式(.t7) 风格迁移预训练模型,这类模型体积小、推理速度快,适合实时场景:

1.模型下载:可从 OpenCV 官方示例库、GitHub 开源仓库获取星月夜(starry_night.t7)、缪斯(la_muse.t7)、海浪(the_wave.t7)、马赛克(mosaic.t7)等经典模型;

2.路径配置:在项目根目录下创建model文件夹,将下载的所有.t7 模型放入其中,保证代码中模型路径与实际文件一致。

二、核心功能模块

2.1 模型加载模块:load_style_model

功能:封装 OpenCV dnn 模型加载逻辑,接收模型文件路径,返回加载好的神经网络对象,为后续风格迁移做准备。

python 复制代码
import cv2

def load_style_model(model_path):
    net = cv2.dnn.readNet(model_path)  # 加载预训练模型
    return net

cv2.dnn.readNet()是 OpenCV dnn 模块的通用模型加载函数,支持 Torch(.t7)、Caffe(.prototxt/.caffemodel)、TensorFlow(.pb)等多种格式

2.2 风格迁移处理模块:apply_style_transfer

功能:接收单区域画面、加载好的风格模型、模型输入目标尺寸,完成图像预处理→模型前向传播→结果后处理的完整风格迁移流程,返回风格化后的单区域画面,是项目的核心算法模块。

python 复制代码
import cv2
import numpy as np

def apply_style_transfer(frame, net, target_size=None):
    h, w = frame.shape[:2]
    if target_size is None:
        target_size = (w, h)

    # 预处理:转换为dnn模块支持的blob格式
    blob = cv2.dnn.blobFromImage(frame, 1, target_size, (0, 0, 0), swapRB=False, crop=False)

    # 前向传播:输入blob,获取风格化结果
    net.setInput(blob)
    output = net.forward()

    # 后处理:恢复维度、归一化、转换为常规图像格式
    output = output.reshape(output.shape[1], output.shape[2], output.shape[3])
    cv2.normalize(output, output, norm_type=cv2.NORM_MINMAX)
    output = output.transpose(1, 2, 0)

    # 恢复原区域尺寸
    output = cv2.resize(output, (w, h))
    return output

1.尺寸初始化:若未指定目标尺寸,默认使用输入画面的原始尺寸,保证兼容性

2.图像预处理(blob 转换):

cv2.dnn.blobFromImage()是 dnn 模块的核心预处理函数,将常规的 HWC(高度 - 宽度 - 通道)格式图像转换为 NCHW(批次 - 通道 - 高度 - 宽度)格式的 blob(深度学习模型标准输入格式);

参数说明:scale=1(像素值不缩放)、mean=(0,0,0)(不做均值消减)、swapRB=False(风格模型要求 RGB 格式,OpenCV 读取的图像为 BGR,需根据模型需求调整)、crop=False(不裁剪,保持画面完整)

3.模型前向传播:net.setInput(blob)设置模型输入,net.forward()执行推理计算,直接输出风格化后的特征图

4.结果后处理

reshape:调整特征图维度,适配后续处理;

cv2.normalize():使用 MINMAX 归一化,将特征图数值映射到 [0,1] 区间,避免像素值溢出;

transpose:将 NCHW 格式转回 HWC 格式,恢复为常规图像的维度顺序;

resize:将风格化后的画面恢复为原区域尺寸,保证拼接后无变形。

2.3 主程序模块:main

功能:项目的入口和总控模块,整合所有功能,完成参数配置→摄像头初始化→模型批量加载→主循环实时处理→资源释放的完整流程,是程序的运行核心。

2.3.1配置参数定义

将所有可自定义的参数集中定义,便于后续调试和修改

python 复制代码
# 摄像头ID,默认0为电脑内置摄像头,外接摄像头可改为1/2
CAMERA_ID = 0
# 四格区域与对应风格模型的映射,键为区域名称,值为模型文件路径
MODEL_PATHS = {
    "top_left": r"model\starry_night.t7",
    "top_right": r"model\la_muse.t7",
    "bottom_left": r"model\the_wave.t7",
    "bottom_right": r"model\mosaic.t7"
}
TARGET_SIZE = (200, 140)  # 模型输入尺寸,越小推理速度越快,可根据性能调整
ESC_KEY = 27  # Esc键的ASCII码,用于退出程序
2.3.2 摄像头初始化

调用 OpenCV 的 VideoCapture 类打开摄像头

python 复制代码
# 打开摄像头
cap = cv2.VideoCapture(CAMERA_ID)
if not cap.isOpened():
    print(f"错误:无法打开摄像头(ID={CAMERA_ID})")
    return
2.3.3 预训练模型批量加载

通过字典推导式批量加载 MODEL_PATHS 中的所有风格模型,加入异常捕获,若模型加载失败则释放摄像头并退出程序

python 复制代码
try:
    models = {
        key: load_style_model(path) for key, path in MODEL_PATHS.items()
    }
    print("所有风格模型加载成功!")
except Exception as e:
    print(f"模型加载失败:{e}")
    cap.release()  # 及时释放摄像头资源
    return
2.3.4 实时采集与风格迁移

这是程序的核心执行循环,实现摄像头帧读取→画面四格分割→多风格并行迁移→画面拼接→实时展示的完整逻辑

python 复制代码
while True:
    # 1. 读取摄像头帧,ret为是否读取成功,frame为采集到的画面
    ret, frame = cap.read()
    if not ret:
        print("错误:无法读取摄像头画面")
        break

    # 2. 获取原画面尺寸,计算分割点(画面中心)
    h, w, c = frame.shape
    h_half, w_half = h // 2, w // 2

    # 3. 四格画面分割:基于numpy切片,高效分割无冗余
    top_left = frame[0:h_half, 0:w_half, :]
    top_right = frame[0:h_half, w_half:w, :]
    bottom_left = frame[h_half:h, 0:w_half, :]
    bottom_right = frame[h_half:h, w_half:w, :]

    # 4. 为每个区域应用对应风格迁移,调用封装的处理函数
    top_left_style = apply_style_transfer(top_left, models["top_left"], TARGET_SIZE)
    top_right_style = apply_style_transfer(top_right, models["top_right"], TARGET_SIZE)
    bottom_left_style = apply_style_transfer(bottom_left, models["bottom_left"], TARGET_SIZE)
    bottom_right_style = apply_style_transfer(bottom_right, models["bottom_right"], TARGET_SIZE)

    # 5. 画面拼接:先水平拼接行,再垂直拼接列,基于numpy的hstack/vstack,高效无失真
    top_row = np.hstack((top_left_style, top_right_style))  # 水平拼接左上、右上
    bottom_row = np.hstack((bottom_left_style, bottom_right_style))  # 水平拼接左下、右下
    final_frame = np.vstack((top_row, bottom_row))  # 垂直拼接上下两行

    # 6. 尺寸校准:保证拼接后画面与原摄像头画面尺寸一致,避免显示变形
    final_frame = cv2.resize(final_frame, (w, h))

    # 7. 实时展示风格化后的完整画面
    cv2.imshow("Camera 4-Grid Art Style Transfer", final_frame)

    # 8. 按键检测:60ms延迟,平衡画面流畅度和按键响应速度,0xFF处理跨平台按键兼容
    key = cv2.waitKey(60) & 0xFF
    if key == ESC_KEY:
        print("用户按下Esc键,退出程序")
        break
  • 采用 numpy 切片分割画面,比 OpenCV 的 ROI 提取更高效,无内存冗余

  • 风格迁移函数批量调用,每个区域独立处理,无相互干扰

三、结果显示

相关推荐
愚公搬代码2 小时前
【愚公系列】《AI短视频创作一本通》002-AI引爆短视频创作革命(短视频创作者必备的能力)
人工智能
数据猿视觉3 小时前
新品上市|奢音S5耳夹耳机:3.5g无感佩戴,178.8元全场景适配
人工智能
蚁巡信息巡查系统3 小时前
网站信息发布再巡查机制怎么建立?
大数据·人工智能·数据挖掘·内容运营
AI浩3 小时前
C-RADIOv4(技术报告)
人工智能·目标检测
Purple Coder3 小时前
AI赋予超导材料预测论文初稿
人工智能
Data_Journal3 小时前
Scrapy vs. Crawlee —— 哪个更好?!
运维·人工智能·爬虫·媒体·社媒营销
云边云科技_云网融合3 小时前
AIoT智能物联网平台:架构解析与边缘应用新图景
大数据·网络·人工智能·安全
康康的AI博客3 小时前
什么是API中转服务商?如何低成本高稳定调用海量AI大模型?
人工智能·ai
技术与健康3 小时前
AI Coding协作开发工作台 实战案例:为电商系统添加用户评论功能
人工智能
在下胡三汉3 小时前
怎么在线编辑修改查看glb/gltf格式模型,支持多选,反选择多物体,单独导出物体(免费)
人工智能