使用预训练VGG19处理视频数据集时遇输入形状及OpenCV缩放错误求助
解决视频分类时的输入形状与OpenCV断言错误
我来帮你拆解并解决遇到的两个核心问题,同时优化代码的线程逻辑:
错误1:输入张量形状不匹配VGG19要求
Keras版本的VGG19默认采用通道后置的输入格式:(224, 224, 3)(高度、宽度、通道数),但你的代码里用image.transpose((2, 0, 1))把通道移到了最前面,变成了(3, 224, 224)(这是PyTorch常用的通道前置格式),直接导致了形状不匹配的报错。
修复方法:移除image.transpose((2, 0, 1))这一行,改用np.expand_dims增加batch维度即可。
错误2:OpenCV resize断言失败
当视频读到最后一帧时,cap.read()会返回ret=False,此时original是空的,调用cv2.resize就会触发!ssize.empty()的断言错误。
修复方法:每次读取帧后立即检查ret的值,如果为False就退出循环,停止处理空帧。
额外的线程逻辑优化
你当前的代码会在每次外层循环创建新线程,这会导致大量线程重复创建销毁,严重拖慢性能。应该只创建一个线程,让它持续处理主线程传递的帧。
修正后的完整代码
from keras.applications.vgg19 import decode_predictions from keras.applications.vgg19 import VGG19, preprocess_input import threading, cv2 import numpy as np label = '' frame = None stop_event = threading.Event() # 用于优雅停止线程 class MyThread(threading.Thread): def __init__(self): super().__init__() self.model = VGG19(weights="imagenet") # 提前加载模型,避免重复加载 def run(self): global label, frame while not stop_event.is_set(): if frame is not None: # 处理帧并更新label preds = self.predict(frame) if preds: inID, label, _ = preds[0] # 解构decode_predictions的返回值 def predict(self, frame): # 转换颜色空间并预处理 image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB).astype(np.float32) image = np.expand_dims(image, axis=0) # 增加batch维度 image = preprocess_input(image) preds = self.model.predict(image, verbose=0) # verbose=0关闭预测日志 return decode_predictions(preds)[0] videoFile = "D:/lostpanda.mp4" cap = cv2.VideoCapture(videoFile) # 仅启动一次线程 keras_thread = MyThread() keras_thread.start() while cap.isOpened(): ret, original = cap.read() # 检查是否成功读取帧 if not ret: break # 调整帧大小到VGG19要求的尺寸 frame = cv2.resize(original, (224, 224)) # 在原始帧上绘制标签 cv2.putText(original, "Label: {}".format(label), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) cv2.imshow("Classification", original) # 按下q键可手动退出 if cv2.waitKey(1) & 0xFF == ord('q'): break # 停止线程并释放所有资源 stop_event.set() keras_thread.join() cap.release() cv2.destroyAllWindows() frame = None
关键修正点说明
- 移除通道转置操作,保持Keras要求的通道后置格式,用
np.expand_dims添加batch维度。 - 增加帧读取有效性检查,避免处理空帧导致的resize错误。
- 线程仅初始化一次,用
stop_event优雅终止线程,避免资源泄漏。 - 模型在线程初始化时提前加载,避免重复加载浪费计算资源。
- 添加手动退出逻辑,解决原代码窗口无法关闭的问题。
内容的提问来源于stack exchange,提问作者abaair davis
相关产品推荐
相关产品推荐

