Python3 OpenCV保存灰度视频时out.write()正确放置位置问题
OpenCV 灰度视频保存中
out.write()的正确放置方式 放置规则
out.write(待写入帧)没有强制的固定位置,只要满足两个条件即可正常工作,放在imshow前后都不影响最终写入结果:
- 必须在确认读到有效帧之后调用,也就是
video.read()返回ret=True的代码段内,视频读完返回ret=False时不能再调用write - 必须在所有帧预处理操作(转灰度、翻转、裁剪、缩放等)全部完成之后调用,否则写入的是未完成处理的帧
你贴的代码里
out.write(gray_video)的位置本身没有逻辑错误,保存失败基本是配套参数或资源释放的问题导致的。
现有代码的问题点
- 帧尺寸不匹配:初始化
VideoWriter时指定输出分辨率为(640,480),但读取的原视频帧没有做对应缩放,如果原视频分辨率不是640*480,OpenCV会静默丢弃所有待写入帧,最终输出0字节的损坏文件,不会主动抛错 - 资源未完全释放:代码只调用了
video.release()释放输入视频对象,没有调用out.release()释放写入器对象,在Jupyter Notebook环境下很容易导致视频内容没有完全刷入磁盘,最终文件无法打开 - 变量传参错误:定义了翻转后的
gray_frame变量,但写入时传入的是未翻转的gray_video,如果预期保存翻转后的灰度视频,这里参数写错了 - 冗余判断:代码开头已经判断
if not ret: break,循环后续代码必然是读到有效帧的状态,后面再写if ret == True属于多余逻辑
修正后可直接运行的代码
import cv2 import numpy as np # 读取输入视频 video = cv2.VideoCapture("video1.mp4") # 直接读取原视频帧率,不用硬编码10帧,输出视频观感和原视频一致 fps = video.get(cv2.CAP_PROP_FPS) # 固定输出分辨率为640*480,如果要和原视频分辨率一致,可以读取原视频宽高赋值 out_size = (640, 480) fourcc = cv2.VideoWriter_fourcc(*'XVID') # 最后一个参数传0代表写入灰度帧,匹配转灰度的需求 out = cv2.VideoWriter('out_gray_scale.mp4', fourcc, fps, out_size, 0) while True: ret, frame = video.read() # 未读到有效帧(视频读完/读取出错)直接退出循环 if not ret: print("视频处理完成") break # 按顺序做帧预处理:缩放到输出尺寸 -> 转灰度 -> 翻转 frame_resized = cv2.resize(frame, out_size) gray_video = cv2.cvtColor(frame_resized, cv2.COLOR_BGR2GRAY) gray_frame = cv2.flip(gray_video, 0) # 所有预处理完成后写入帧,位置放imshow前后都不影响结果 out.write(gray_frame) # 不需要翻转的话就传入gray_video # 显示处理后的帧 cv2.imshow("video grayscale", gray_frame) # 按q键提前退出处理 if cv2.waitKey(25) & 0xFF == ord('q'): break # 必须释放两个对象,再销毁所有弹窗 video.release() out.release() cv2.destroyAllWindows()
Jupyter环境运行注意事项
如果运行时出现弹窗无响应、内核崩溃的情况,可以先把cv2.imshow相关的显示逻辑注释掉,先验证视频可以正常保存,再调试显示部分;处理完大体积视频后建议重启内核释放内存,避免后续文件读写出现权限异常。
内容的提问来源于stack exchange,提问作者daryk1
相关产品推荐
相关产品推荐

