将摄像头实时画面分割成四个方格,每个方格应用不同的艺术风格滤镜,最后拼接成一个完整画面展示出来
本项目的核心需求可以清晰拆解为五个关键模块:
-
摄像头实时画面采集:调用电脑默认摄像头,持续获取原始视频帧;
-
图像缩放优化:对高分辨率原始帧进行缩放,从根源降低计算压力,避免卡顿;
-
四宫格画面分割:将缩放后的画面均匀切分为左上、右上、左下、右下四个等大区域;
-
分区域风格迁移:为四个象限分别加载不同的艺术风格模型,独立完成风格转换;
-
画面拼接与实时展示:将处理后的四个艺术化区域重新拼接,实时显示最终效果,并支持按键退出。
风格迁移模型准备
项目使用四个经典的 **.t7 格式轻量化风格迁移模型 **,该格式由 Torch 框架训练而成,体积小、推理速度快,完美适配实时场景。四个模型分别对应:
-
starry_night.t7:梵高《星月夜》油画风格; -
candy.t7:糖果艺术几何风格; -
the_wave.t7:海浪艺术抽象风格; -
the_scream.t7:蒙克《呐喊》艺术风格。
模型文件可从计算机视觉公开资源库下载,获取后建议存放至英文路径文件夹(避免中文路径导致 OpenCV 模型加载失败),后续代码中只需修改模型路径即可适配本地环境。
预训练模型加载函数
python
def load_style_model(model_path):
"""加载预训练的风格迁移模型"""
return cv2.dnn.readNet(model_path)
该函数是项目的基础工具,接收模型文件路径作为参数,调用cv2.dnn.readNet方法加载深度学习模型并返回网络对象。OpenCV 的 dnn 模块支持直接读取.t7、.onnx 等多种格式的预训练模型,无需额外搭建深度学习环境,极大简化了模型部署流程。将模型加载封装为独立函数,可实现代码复用,避免主逻辑中重复编写加载语句。
单帧风格迁移处理函数
python
def apply_style_transfer(frame, model, target_size):
"""对单帧画面应用风格迁移"""
# 缩放输入帧以匹配模型输入尺寸
frame_resized = cv2.resize(frame, target_size)
# 构建输入blob
blob = cv2.dnn.blobFromImage(
frame_resized,
scalefactor=1.0,
size=target_size,
mean=(0, 0, 0),
swapRB=False,
crop=False
)
# 风格迁移推理
model.setInput(blob)
output = model.forward()
# 处理输出结果
output = output.reshape(output.shape[1], output.shape[2], output.shape[3])
cv2.normalize(output, output, 0, 255, cv2.NORM_MINMAX)
result = output.transpose(1, 2, 0).astype(np.uint8)
# 调整回原始子帧尺寸
return cv2.resize(result, (frame.shape[1], frame.shape[0]))
该函数是项目的核心功能模块,负责对单个图像区域完成风格迁移,同时也是解决实时卡顿的关键。其逻辑可分为五步:
-
输入缩放:将图像区域调整为模型要求的 224×224 尺寸,小尺寸输入能大幅提升推理速度;
-
Blob 构建 :通过
cv2.dnn.blobFromImage将图像转换为深度学习模型支持的 Blob 格式,完成通道、维度的标准化处理; -
模型推理:将 Blob 输入模型,执行前向传播得到风格迁移后的输出数据;
-
结果归一化:对模型输出数据进行维度调整、像素值归一化,转换为 OpenCV 可识别的图像格式;
-
尺寸还原:将处理后的小尺寸图像还原为原始区域尺寸,保证后续拼接时画面比例一致。
主逻辑函数:实时处理全流程
python
def main():
# 1. 初始化摄像头与缩放参数
cap = cv2.VideoCapture(0)
scale_factor = 0.5 # 缩放以降低卡顿
original_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
original_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
scaled_width = int(original_width * scale_factor)
scaled_height = int(original_height * scale_factor)
half_w, half_h = scaled_width // 2, scaled_height // 2
model_input_size = (224, 224) # 风格迁移模型的输入尺寸
# 2. 加载四个不同的风格迁移模型
style_models = [
load_style_model(r"模型路径\starry_night.t7"),
load_style_model(r"模型路径\candy.t7"),
load_style_model(r"模型路径\the_wave.t7"),
load_style_model(r"模型路径\the_scream.t7")
]
while True:
ret, frame = cap.read()
if not ret:
break
# 3. 缩放整个画面
frame_scaled = cv2.resize(frame, (scaled_width, scaled_height))
# 4. 分割画面为四个象限
quadrants = [
frame_scaled[0:half_h, 0:half_w], # 左上
frame_scaled[0:half_h, half_w:], # 右上
frame_scaled[half_h:, 0:half_w], # 左下
frame_scaled[half_h:, half_w:] # 右下
]
# 5. 为每个象限应用不同风格
styled_quadrants = [
apply_style_transfer(quadrants[i], style_models[i], model_input_size)
for i in range(4)
]
# 6. 拼接处理后的画面
top_row = np.hstack([styled_quadrants[0], styled_quadrants[1]])
bottom_row = np.hstack([styled_quadrants[2], styled_quadrants[3]])
final_frame = np.vstack([top_row, bottom_row])
# 7. 显示最终画面
cv2.imshow('4-Style Real-Time Transfer', final_frame)
# 按ESC键退出
if cv2.waitKey(1) == 27:
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
主函数是项目的总控中心,串联起所有功能模块,核心逻辑如下:
-
摄像头初始化 :通过
cv2.VideoCapture(0)调用默认摄像头,设置缩放系数为 0.5,将原始画面缩小 50%,进一步降低计算压力; -
参数计算:获取原始画面分辨率,计算缩放后的尺寸与半宽、半高值,为四宫格分割做准备;
-
多模型加载:一次性加载四个风格模型,存储为列表,方便按象限索引对应调用;
-
实时帧读取:通过 while 循环持续读取摄像头帧,判断帧读取状态,失败则退出循环;
-
画面缩放与分割:对原始帧进行缩放,利用 NumPy 数组切片将画面切分为四个等大象限;
-
分区域风格处理:遍历四个象限,分别调用对应模型完成风格迁移;
-
画面拼接与展示 :使用
np.hstack完成左右拼接,np.vstack完成上下拼接,最终显示四风格合一的实时画面,按下 ESC 键即可退出; -
资源释放:循环结束后释放摄像头、关闭所有窗口,避免资源占用。
运行结果:

本项目的核心优化点完美解决了实时图像处理的痛点,是项目流畅运行的关键:
-
双层缩放优化:第一层是摄像头原始帧整体缩放,第二层是模型输入尺寸缩放,双层优化让推理速度提升数倍,在不明显损失视觉效果的前提下,彻底解决卡顿问题;
-
轻量化模型选型:选用.t7 格式轻量化快速风格迁移模型,相比大型深度学习模型,体积更小、推理更快,对 CPU 配置无过高要求;
-
模块化代码设计:将模型加载、风格迁移封装为独立函数,主逻辑仅负责流程调度,代码可读性、可扩展性大幅提升;
-
高效矩阵操作:利用 NumPy 原生的切片、拼接函数,避免循环遍历像素,提升图像处理效率。