大家好,
我有一个在Keras中训练的CNN-LSTM模型。作为输入,我加载了每段视频15帧,每帧大小为30×30,且只有一个通道(15, 30, 30, 1)。
这些帧是从总共279个视频中提取的,并存储在一个大张量中,尺寸为(279, 15, 30, 30, 1)。
X_data.shape = (279, 15, 30, 30, 1)y_data.shape = (279,)
我处理的是两类视频(因此目标是0和1)。
我的时间分布式CNN的输入层(在我的LSTM层之前)是:
input_layer = Input(shape=(None, 30, 30, 1))
好的,这些数据已经输入到我的网络中,一切运行良好,但现在我需要预测这些视频,并且我想在正在分类的视频中显示输出结果。
我编写了以下代码来读取视频并显示文本:
vid = cv2.VideoCapture(video_path)while(vid.isOpened()): ret, frame = vid.read() if ret == True: texto = predict_video(frame) frame = cv2.resize(frame,(750,500),interpolation=cv2.INTER_AREA) frame = cv2.putText(frame,str(texto),(0,130), cv2.FONT_HERSHEY_SIMPLEX, 2.5, (255, 0, 0), 2, cv2.LINE_AA) cv2.imshow('Video', frame) if cv2.waitKey(25) & 0xFF == ord('q'): break else: breakvid.release()cv2.destroyAllWindows()
predict_video() 函数用于生成预测输出作为文本,如您所见:
def predict_video(frame): count_frames = 0 frame_list = [] frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) frame = cv2.resize(frame,(30,30),interpolation=cv2.INTER_AREA) while count_frames < 15: frame_list.append(frame) count_frames = 0 frame_set = np.array(frame_list) frame_set = frame_set.reshape(1, 15, 30, 30, 1) pred = model.predict(frame_set) pred_ = np.argmax(pred,axis=1) #我使用的是Keras的Model对象 if pred_ == 1: return 'Archery' elif pred_ == 0: return 'Basketball'
由于CNN-LSTM的输入维度等于(None, 30, 30, 1),我需要使用 model.predict(sample) 来预测一个样本,其维度应为(1, 15, 30, 30, 1)。如何实时预测视频,而不仅仅是逐帧预测,而是基于15帧集的模型进行预测呢?
当前的predict_video()函数会使我的电脑“冻结”。
谢谢您的关注!
回答:
以下是一段可以在每帧上添加文本的代码
cv2.putText(img, text, (textX, textY ), font, 1, (255, 255, 255), 2)
这里的”img”是您的帧,”text”是您的预测输出,而”textX和textY”是您希望文本居中的坐标。至于您的问题的另一部分,即如何基于15帧集而不是单帧进行预测,您可以这样做:在Keras中训练模型时,将批次大小设置为15帧,并为每帧提供真实标签。完成训练后,模型将期望您输入15帧的批次。之后,在while循环中,您可以设置一个检查,当通过的帧数达到15时,您收集这些帧并创建一个维度为(15,30,30,1)
的张量。
这部分代码
frame_list = []while count_frames < 15: frame_list.append(frame)
不应该放在函数内部,因为每次调用函数时,frame_list都会被重置为零,因为它的作用域仅限于函数内。您应该将这段代码写在for循环内,当frame_list
中的帧数达到15时,您应该调用model.predict(batch)
函数,并首先扩展维度以设置为(1,15,30,30,1)
。