视频可以简单看作一系列图片的集合
我的BiliBili视频教程(知道你不喜欢看文字)
1. 视频分类简介
视频分类通过有以下几种方法:
- 2DCNN + LSTM
- 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. 全部代码
为了方便大家的使用,我将全部代码见 【Github】
使用方法:
- 运行create_image.py文件,生成视频采样特征。
- 运行main.py文件,训练模型
- 运行predict.py文件,进行预测
公众号【自由小兵儿】,回复【数据集100】,可以得到数据集,并且通过公众号可第一时间联系到我呀!