You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将原始OpenCV图像保存为视频?现有代码生成无效视频问题求助

OpenCV生成无效视频的问题解决方案

代码核心错误

  • VideoWriter初始化时传入的帧尺寸是原始窗口大小,但是实际写入的帧是缩放2/3之后的尺寸,两者不匹配,这是OpenCV写视频失败最常见的原因。
  • 循环退出后没有调用release_vw()方法释放VideoWriter,导致视频文件头没有正确写入,文件直接损坏。
  • 未校验pywin32采集的图像格式,可能存在通道数、通道顺序不符合要求的问题。

OpenCV写入视频的图像格式要求

  • 所有输入帧的宽高必须和VideoWriter初始化时传入的frame_size参数完全一致,frame_size参数格式为(宽度, 高度),注意和numpy数组的(高度, 宽度, 通道数)的顺序区分。
  • 图像数据类型必须是np.uint88位无符号整数。
  • 图像通道顺序必须是BGR,不能是RGB;如果使用XVID等普通编码器,输入必须是3通道图像,不能带alpha通道。

代码修改方案

1. 调整VideoWriter初始化参数

使用缩放后的帧尺寸初始化VideoWriter:

def __init__(self, window_capture=None, fps=5):
    self.fps = fps
    self.frame_time_limit = 1/self.fps
    self.window_capture = window_capture
    # 获取原始窗口尺寸
    self.frame_width, self.frame_height, self.frame_size = self.window_capture.get_frame_dimentions()
    self.scaling_factor = 2/3
    # 计算缩放后的实际帧尺寸
    self.scaled_width = int(self.frame_width * self.scaling_factor)
    self.scaled_height = int(self.frame_height * self.scaling_factor)
    # 用实际写入的尺寸初始化视频写入器
    self.output_video = cv.VideoWriter(
        f'assets{sep}Videos{sep}test.avi',
        cv.VideoWriter_fourcc(*'XVID'),
        self.fps,
        (self.scaled_width, self.scaled_height))

2. 调整update方法里的帧处理逻辑

增加格式校验,统一帧尺寸:

def update(self, dt):
    if self.filming:
        self.time_elapsed += dt
        if self.time_elapsed >= self.frame_time_limit:
            self.time_elapsed -= self.frame_time_limit
            frame = self.window_capture.get_screenshot()
            # 格式转换:如果是4通道带alpha,转成3通道BGR
            if frame.shape[-1] == 4:
                frame = cv.cvtColor(frame, cv.COLOR_BGRA2BGR)
            # 格式转换:如果采集的是RGB顺序,转成BGR
            # frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR)
            # 直接指定缩放后的尺寸,避免浮点计算误差导致的尺寸不匹配
            frame = cv.resize(frame, dsize=(self.scaled_width, self.scaled_height))
            self.output_video.write(frame)
            cv.imshow("Computer Vision", frame)

3. 补充循环退出后的释放逻辑

按q退出后必须执行资源释放:

vsc.start()
loop_time = time()
while cv.waitKey(1) != ord('q'):
    vsc.update(time() - loop_time)
    loop_time = time()
# 释放视频写入器、销毁窗口
vsc.release_vw()
cv.destroyAllWindows()

关于输入VideoCapture类的替代方案

你当前使用pywin32直接采集窗口图像的方案已经可以满足需求,不需要额外再用VideoCapture捕获窗口,也不需要绕路捕获cv.imshow的窗口,改完上述问题后就可以直接生成可用的测试视频。

内容的提问来源于stack exchange,提问作者The-Heart-Of-Gold42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:15:05