简单视频分类模型

视频可以简单看作一系列图片的集合

1. 视频分类简介

视频分类通过有以下几种方法:

  1. 2DCNN + LSTM
  2. 3DCNN

本文仅仅介绍最简单的2DCNN + LSTM的方法,使用tensorflow 2.0+ 进行实现,保证代码尽可能简短,但性能将会一般。

2. 数据集准备

虽然视频是由很多帧构成的,但是如果我们选取所有帧会消耗大量的计算资源,并且不同视频帧数不同会导致LSTM的输入不确定。为了保证所有视频提取出的所有帧数量相同,本文使用最简单的方法进行预处理(等间隔采样法)。

等间隔采样方法示例:无论视频多长我们都想采样出4帧来。那么一个32帧的视频,我们就需要每8帧取一帧。最后我们的采样结果是第{1,9,17,25}帧。

具体代码实现为:

def read_video(video_path):
    # 等间隔采样法
    need_number = 8
    images = []
    cap = cv2.VideoCapture(video_path)
    frames_num = cap.get(7) - 1
    step = frames_num // need_number
    print("总帧数: ", frames_num, "步长:", step)
    i = 0
    frames = 0
    while cap.isOpened():
        ret, frame = cap.read()
        i = i+1
        if frames == need_number:
            cap.release()
            break
        if (i % step == 0):
            frames = frames + 1
            frame = transform.resize(frame, (150, 80))
            images.append(frame)
    return np.asarray(images, np.float32)

该方法具有帧浪费的现象,但是本文尽可能保证代码简单,如有优化兴趣,请见参考文献1。

3. 模型搭建

模型搭建,本文使用tensorflow中的keras进行快速搭建,几行代码就可以搞定。

model = Sequential([
    TimeDistributed(Conv2D(2, (2,2), activation= 'relu'), input_shape=(None,150,80,3)),
    TimeDistributed(MaxPooling2D(pool_size=(2, 2))),
    TimeDistributed(Flatten()),
    LSTM(256),
    Dense(1, activation='sigmoid'),
])

这里解释一下TimeDistributed层的意思,我们的输入是一个时间序列数据,就像这样[图片1,图片2,图片3,图片4],我们需要对每个图片都进行CNN特征提取,所以TimeDistributed层就是对每个时刻的数据进行函数内的操作。

最后我们将所有采样出的图片的特征,输入到LSTM中进行分类。

4. 全部代码

为了方便大家的使用,我将全部代码(包含小型数据集)都打包放在云盘当中去。如果觉得不错希望在评论区留下你的足迹。

使用方法:

  1. 运行create_image.py文件,生成视频采样特征。
  2. 运行main.py文件,训练模型
  3. 运行predict.py文件,进行预测

阿里云盘链接:https://www.aliyundrive.com/s/B6bfXkVkr2p (呜呜呜,阿里不能分享压缩包,我只能分享文件夹了)

如果不能下载,给我留言我会发给你的。

5. 参考资料

  1. CSDN-2D卷积神经网络+LSTM实现视频动作分类