使用OpenCV裁剪视频帧遇!_img.empty()错误,求解决方法
问题分析与解决方案
错误根源
- 帧读取逻辑错误:原代码仅调用一次
cap.read(),只获取了视频的第一帧,随后的for img in frames是遍历该帧的颜色通道(如BGR三通道),而非遍历视频的所有帧。 - 无效裁剪或空数据:遍历通道得到的单通道数组,执行
img[500:1300,100:1000]时,因维度不匹配会生成空数组,导致cv2.imwrite触发!_img.empty()断言错误。 - 未定义变量:代码中
stops变量未初始化,会先引发NameError。
修正代码
import cv2 import os # 确保输出目录存在,避免写入失败 output_dir = "../stack" if not os.path.exists(output_dir): os.makedirs(output_dir) cap = cv2.VideoCapture(r"C:\Users\HP\Downloads\VID_20221128_112556.mp4") count = 0 stops = [] # 初始化存储帧的列表 # 循环读取视频所有帧 while cap.isOpened(): ret, frame = cap.read() # 读取失败或视频播放完毕时退出循环 if not ret: break # 执行裁剪操作,可先打印frame.shape确认帧尺寸是否符合裁剪范围 cropped_img = frame[500:1300, 100:1000] # 校验裁剪后的图像是否有效,避免写入空数据 if cropped_img.size != 0: cv2.imwrite(os.path.join(output_dir, f"croppedframe{count}.jpg"), cropped_img) stops.append(frame) # 如需存储裁剪后的帧,改为stops.append(cropped_img) print(count) count += 1 # 释放视频资源 cap.release()
关键修复点
- 循环读取帧:用
while cap.isOpened()配合cap.read()实现逐帧读取,直到视频结束。 - 目录预处理:提前创建输出目录,避免因目录不存在导致写入失败。
- 空数据校验:添加
cropped_img.size != 0判断,确保只写入有效的裁剪图像。 - 变量初始化:显式初始化
stops列表,解决未定义错误。
额外建议
- 先打印
frame.shape确认视频帧的实际尺寸,确保500:1300,100:1000的裁剪范围在有效范围内(比如帧高度需≥1300、宽度≥1000),否则裁剪会得到空数组。 - 如果视频无法读取,检查文件路径是否正确,或视频文件是否损坏(可尝试用本地播放器打开验证)。
内容的提问来源于stack exchange,提问作者Omar Morales Rivera
相关产品推荐
相关产品推荐

