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

OpenCV视频保存异常:输出视频仅1kB且无法打开

OpenCV视频保存异常:输出视频仅1kB且无法打开

嘿,我仔细看了你的代码,找到几个导致视频保存失败的核心问题,咱们一步步来解决:

  • VideoWriter通道数不匹配(最关键的问题)
    你创建的new_video是按照彩色视频的规格初始化的(默认是3通道BGR格式),但你写入的所有帧都是单通道灰度图(比如new_frame的形状是(frame_height, frame_width),只有一个通道)。这种不匹配会让视频编码器无法正确写入有效帧,最终生成的文件只有空的文件头,大小就只有1kB,自然无法打开。

    解决方法很简单,二选一就行:

    1. 把灰度帧转换成3通道BGR后写入:每次写入前加一行代码,把单通道转成3通道:
      new_frame_3ch = cv2.cvtColor(new_frame, cv2.COLOR_GRAY2BGR)
      new_video.write(new_frame_3ch)
      
      这样就和你初始化VideoWriter时的彩色格式匹配了,兼容性也更好。
    2. 初始化VideoWriter时适配单通道灰度:修改VideoWriter的初始化参数,加上isColor=False,告诉OpenCV这是灰度视频:
      new_video = cv2.VideoWriter(output_file_name, fourcc, frame_rate, (frame_width, frame_height), isColor=False)
      
      不过这种方式要注意编码器是否支持灰度输出,推荐第一种方法。
  • 循环逻辑的小bug
    你在进入循环前先执行了success, current_video_frame = video.read(),然后循环里第一行又读next_video_frame,这会导致原视频的第一帧被跳过,没有参与后续的差值计算。如果这不是你的预期,可以调整循环逻辑:

    # 先读取第一帧作为current
    success, current_video_frame = video.read()
    while success:
        success, next_video_frame = video.read()
        if not success:
            break
        # 差值处理逻辑...
        current_video_frame = next_video_frame
    
  • 数值溢出的潜在问题
    你用new_frame = new_frame + difference来累加差值,但因为都是uint8类型(取值范围0-255),相加会直接溢出(比如250+10会变成4),这可能不是你想要的视觉效果。建议改用cv2.add或者手动限制最大值:

    # 方式1:用cv2.add自动处理溢出(超过255的部分会被截断为255)
    new_frame = cv2.add(new_frame, difference)
    # 方式2:手动限制最大值
    new_frame = np.clip(new_frame + difference, 0, 255).astype(np.uint8)
    

下面是整合了所有修复点的完整代码,你可以直接运行试试:

import cv2
import numpy as np

file_name = "Touhou - Bad Apple.mp4"
output_file_name = "Touhou - Bad Apple difference flip.mp4"

# Open the video file
video = cv2.VideoCapture(file_name)

# Get the dimensions of the video
frame_width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
frame_rate = video.get(cv2.CAP_PROP_FPS)

# Create a VideoWriter object to write the new video file
fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # Codec for .mp4 files
new_video = cv2.VideoWriter(output_file_name, fourcc, frame_rate, (frame_width, frame_height))

# Create first frame and convert to 3-channel BGR
new_frame = np.random.randint(0, 256, (frame_height, frame_width), dtype=np.uint8)
new_video.write(cv2.cvtColor(new_frame, cv2.COLOR_GRAY2BGR))

# Read first frame of original video
success, current_video_frame = video.read()
while success:
    success, next_video_frame = video.read()
    if not success:
        break

    difference = cv2.absdiff(current_video_frame, next_video_frame)
    difference = cv2.cvtColor(difference, cv2.COLOR_BGR2GRAY)
    
    # Handle overflow when adding frames
    new_frame = cv2.add(new_frame, difference)
    # Convert to 3-channel before writing
    new_video.write(cv2.cvtColor(new_frame, cv2.COLOR_GRAY2BGR))
    
    current_video_frame = next_video_frame

    cv2.imshow('Difference', new_frame)
    if cv2.waitKey(1) == ord('q'):
        break

# Release the video objects
video.release()
new_video.release()
cv2.destroyAllWindows()

备注:内容来源于stack exchange,提问作者Akut Luna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 18:08:08