
在使用python的opencv库进行视频录制时,开发者可能会遇到一个令人困扰的问题:代码运行正常,生成了.mp4或其他格式的视频文件,但文件大小为0kb,或者打开时提示文件损坏无法播放。这通常发生在尝试设置摄像头分辨率并将其直接用于cv2.videowriter初始化时。
典型的错误代码模式如下:
import cv2
cap = cv2.VideoCapture(0)
# 尝试设置摄像头分辨率
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1280)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 720)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 直接使用硬编码的期望分辨率初始化VideoWriter
writer = cv2.VideoWriter('recording.mp4', fourcc, 30.0, (1280, 720))
recording = False
while True:
ret, frame = cap.read()
if ret:
cv2.imshow("video", frame)
if recording:
writer.write(frame) # 写入帧
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('r'):
recording = not recording
cap.release()
writer.release()
cv2.destroyAllWindows()上述代码的问题在于,cap.set()方法虽然尝试设置摄像头分辨率,但摄像头硬件可能不支持请求的特定分辨率,或者操作系统/驱动程序可能将其调整为最接近的支持分辨率。如果cv2.VideoWriter使用的分辨率与cap.read()实际捕获到的帧分辨率不一致,writer.write(frame)将无法正确处理数据,导致输出文件损坏或为空。
问题的核心在于cv2.VideoWriter期望接收的帧尺寸必须与其初始化时指定的尺寸完全一致。当通过cap.set()设置摄像头分辨率时,并不能保证摄像头会严格按照这个分辨率工作。如果摄像头实际输出的分辨率与cv2.VideoWriter初始化时传入的硬编码分辨率不匹配,写入操作就会失败。
解决此问题的关键在于,在初始化cv2.VideoWriter之前,从cv2.VideoCapture对象中动态获取摄像头实际工作时的分辨率。这样可以确保VideoWriter与实际捕获到的帧尺寸保持一致。
立即学习“Python免费学习笔记(深入)”;
修正后的代码示例:
import cv2
# 1. 初始化摄像头捕获对象
cap = cv2.VideoCapture(0)
# 2. 尝试设置期望的分辨率
# 注意:这只是一个尝试,摄像头可能不会严格按照此分辨率工作
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
# 3. 关键步骤:获取摄像头实际工作时的分辨率
# 使用cap.get()获取实际的宽度和高度
# 通常需要四舍五入到整数
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
actual_resolution = (width, height)
print(f"摄像头实际工作分辨率: {actual_resolution}")
# 4. 定义视频编码器和帧率
# 'mp4v' 是一个常见的MP4编码器,兼容性较好。
# 其他编码器如 'XVID' (用于.avi), 'MJPG' (用于.avi) 等。
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
fps = 30.0
# 5. 使用实际分辨率初始化VideoWriter
# 确保写入器的分辨率与摄像头实际输出的帧分辨率一致
writer = cv2.VideoWriter('recording.mp4', fourcc, fps, actual_resolution)
# 录制状态标志
recording = False
print("按 'r' 键开始/停止录制,按 'q' 键退出。")
while True:
ret, frame = cap.read() # 读取一帧
if not ret:
print("无法从摄像头读取帧,退出。")
break
# 显示实时视频
cv2.imshow("实时视频 (按'r'录制, 'q'退出)", frame)
# 如果处于录制状态,则写入帧
if recording:
writer.write(frame)
# 处理按键事件
key = cv2.waitKey(1) & 0xFF # 获取按键,& 0xFF 确保跨平台兼容
if key == ord('q'):
break # 按 'q' 退出循环
elif key == ord('r'):
recording = not recording # 切换录制状态
print(f'录制状态: {"正在录制" if recording else "已暂停"}')
# 6. 释放资源
# 确保在程序结束前释放所有捕获和写入对象,并关闭所有OpenCV窗口
cap.release()
writer.release()
cv2.destroyAllWindows()
print("录制结束,资源已释放。")通过本文的教程,我们了解了使用Python和OpenCV录制视频时0KB或损坏文件问题的根本原因——摄像头实际分辨率与cv2.VideoWriter初始化参数不匹配。核心解决方案是利用cap.get()方法动态获取摄像头实际工作时的分辨率,并将其传递给cv2.VideoWriter。遵循这一最佳实践,并结合适当的错误处理和资源释放,可以确保稳定、可靠地录制高质量的视频文件。
以上就是Python OpenCV 视频录制:解决0KB文件和损坏问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号