news 2026/4/16 21:29:30

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 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 模型加载逻辑,接收模型文件路径,返回加载好的神经网络对象,为后续风格迁移做准备。

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

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

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配置参数定义

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

# 摄像头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 类打开摄像头

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

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

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 实时采集与风格迁移

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

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 提取更高效,无内存冗余

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

三、结果显示

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 11:11:45

OFA-VE开源模型实战:低成本GPU算力方案实现高精度图文逻辑判断

OFA-VE开源模型实战:低成本GPU算力方案实现高精度图文逻辑判断 1. 什么是OFA-VE:不只是模型,而是一套可落地的视觉理解工作流 你有没有遇到过这样的问题:一张商品图配了一段文案,但你不确定文案是否真实反映了图片内…

作者头像 李华
网站建设 2026/4/16 11:13:42

C语言对话-16.Al-Go-Rithms

徐波 翻译 各类报道纷至沓来。地表附近及邻近空间正发生什么事,我根本摸不着头脑。从各种迹象看,亚洲人似乎已经占领了这个地方,但到目前为止,我还没有看到他们。 我和珍妮正与世隔绝般地在地下古城工作。这是一个奇妙的&#x…

作者头像 李华
网站建设 2026/4/16 18:18:50

PHP每次请求重复初始化的庖丁解牛

“PHP 每次请求重复初始化” 是传统 PHP-FPM 模型的核心瓶颈,它导致 框架加载、类解析、配置读取等开销在每次请求中重复发生,严重限制高并发性能。 一、核心机制:请求生命周期 ▶ 1. PHP-FPM 请求流程 #mermaid-svg-zFxmSH64zS6kXbuz{font-…

作者头像 李华
网站建设 2026/4/16 10:04:20

主页加载手动检查流程:软件测试从业者实用指南

在Web应用测试中,主页加载性能直接影响用户体验和业务转化率。手动检查作为自动化测试的补充,能捕捉细微问题,如视觉错位或资源阻塞。本文针对软件测试从业者,系统梳理主页加载的手动检查流程,涵盖准备、执行和问题诊断…

作者头像 李华
网站建设 2026/4/15 22:34:10

Android开发工程师面试指南:基于成都高新菁蓉汇智人才服务有限公司职位需求

成都高新菁蓉汇智人才服务有限公司 Android开发工程师 (MJ000373) 职位信息 岗位职责 1、负责客户端和手机端APP程序的方案和架构设计,开发和维护等工作 2、根据需求完成Android系统应用的需求开发、测试和功能维护,高质量完成产品功能迭代; 3、快速准确理解需求,并通过简洁…

作者头像 李华