Kinetics数据集是行为识别中十分重要的benchmark,其地位相当于图像分类中的ImageNet。本人目前在做小样本行为识别,需要用到Kinetics-400数据集搭建Kinetics-100小样本行为识别数据集。由于种种原因,网上的数据集都有缺失,所以本人基于已经下载的数据集,使用youtube-dl下载缺失视频,仅供大家参考。
1、https://www.codeleading.com/article/23055974480/
该方法用了特定软件将数据集分割成132个小数据集,下载完成后需要使用cat命令完成拼接。对拼接的数据集解压,即可得到Kinetics-400。建议下载好后,在linux下拼接解压或者在windows下安装git bash。
2、https://github.com/PaddlePaddle/PaddleVideo/blob/develop/docs/zh-CN/dataset/k400.md
作者在文中介绍了两种方法,一种是百度网盘下载(数据和第一种方法不一样);另一种使用脚本下载,需要下载官方的trainlist.csv和testlist.csv文件。
和第一种百度网盘方法不同的是,第二种每个子数据集都可以单独解压。不幸的是,第一种方法缺失的视频更多。
https://www.codetd.com/article/5004295
使用youtube-dl工具,根据提供的唯一标识符youtu id下载视频。
1、下载爬取视频代码https://github.com/activitynet/ActivityNet.git
2、安装youtube-dl包
3、安装ffmpeg
注意:使用pip和conda装的ffmpeg会报以下错误
‘ffmpeg’ 不是内部或外部命令,也不是可运行的程序或批处理文件
需要去官网下载源码,解压后可以在bin目录下得到三个文件,如下图所示。
将"E:/ffmpeg/bin"写进环境变量,即可在命令行使用ffmpeg命令。
A. 下载好代码后,进入ActivityNet-master\ActivityNet-master\Crawler\Kinetics目录,准备一个csv文件data.csv,存储需要下载的视频youtube_id、视频开始时间、视频结束时间、后面两个参数不重要,可以直接写train和0。
python download.py data.csv dataset
但是直接运行这个代码频繁报错,各种错误,而且代码里是先下载原始视频,存储在tmp临时目录中,接着使用ffmpeg工具对视频长度裁剪,清空临时目录,将裁剪后视频放到dataset中。
考虑到中间可能会出现各种错误,我对代码进行了部分修改,先从YouTube下载所有需要的视频,存储在videos中。
#此处将后续的ffmpeg裁剪去掉,同时修改了输出文件位置及视频名称,下载的视频以_kDc7gYphkU_000193_000203.mp4即id_start-time_end-time.mp4 格式命名。方便后续直接根据视频名字读取长度信息进行视频裁剪。
def download_clip(video_identifier, output_filename,
start_time, end_time,
tmp_dir='/tmp/kinetics',
num_attempts=5,
url_base='https://www.youtube.com/watch?v='):
"""Download a video from youtube if exists and is not blocked.
arguments:
---------
video_identifier: str
Unique YouTube video identifier (11 characters)
output_filename: str
File path where the video will be stored.
start_time: float
Indicates the begining time in seconds from where the video
will be trimmed.
end_time: float
Indicates the ending time in seconds of the trimmed video.
"""
# Defensive argument checking.
assert isinstance(video_identifier, str), 'video_identifier must be string'
assert isinstance(output_filename, str), 'output_filename must be string'
assert len(video_identifier) == 11, 'video_identifier must have length 11'
status = False
# Construct command line for getting the direct video link.
tmp_filename = os.path.join(tmp_dir,
'%s.%%(ext)s' % uuid.uuid4())
#print("origin",tmp_filename)
command = ['youtube-dl',
'--quiet', '--no-warnings',
'-f', 'mp4',
'-o', '"%s"' % output_filename,
'"%s"' % (url_base + video_identifier)]
# print('%s*' % (tmp_filename.split('.')[0]))
# print(glob.glob('%s*' % tmp_filename.split('.')[0]))
# tmp_filename = glob.glob('%s*' % (tmp_filename.split('.')[0]))[0]
command = ' '.join(command)
print(command)
attempts = 0
while True:
try:
output = subprocess.check_output(command, shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as err:
attempts += 1
if attempts == num_attempts:
return status, err.output
else:
break
B. 读取下载视频,使用ffmpeg工具剪切视频
def read(dir,out_dir):
vid = os.listdir(dir)
for k in vid:
id = k.split('.')[0]
vid_path = os.path.join(dir,id)
start_time = int(id.split('_')[-2])
end_time = int(id.split('_')[-1])
vid_name = id.split('_')[0] + id.split('_')[1]
print("{} {} {} {}".format(vid_path,vid_name,start_time,end_time))
out_file = os.path.join(out_dir,vid_name+".mp4")
status = False
command = ['ffmpeg',
'-i', '"%s"' % os.path.join(dir,k),
'-ss', str(start_time),
'-t', str(end_time - start_time),
'-c:v', 'libx264', '-c:a', 'copy',
'-threads', '1',
'-loglevel', 'panic',
'"%s"' % out_file]
command = ' '.join(command)
print(command)
try:
output = subprocess.check_output(command, shell=True,
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as err:
return status, err.output
C. 根据配置文件,分析每个视频的动作类别,存储在act字典中,后续读取字典,创建相应动作类别目录,存储RGB帧
def parse(file):
act = {}
with open(file, "r") as fid:
data = fid.readlines()
#print(data)
for i in range(len(data)):
action = data[i].split('/')[0]
vid = data[i].split('/')[1]
if len(vid.split('_')) == 4:
vid_name = vid.split('_')[0] + vid.split('_')[1]
else:
vid_name = vid.split('_')[0]
act[vid_name] = action
#print("{} {}".format(action,vid_name))
return act
D. 使用ffmpeg工具提取视频RGB帧
def run_RGB_copy(source_path,target_path):
# 读取视频文件
cmd = 'ffmpeg'+' -i {} {}/image-%6d.jpg'.format(
source_path,target_path)
print(cmd)
os.system(cmd)
print('{} done'.format(source_path))
sys.stdout.flush()
return True
def RGB(out_dir,img_dir,file):
#read videos
vid = os.listdir(out_dir)
act = parse(file)
print(vid)
for i in range(len(vid)):
video_path = os.path.join(out_dir,vid[i])
action = act[vid[i].split('.')[0]]
target_action_path = os.path.join(img_dir,action)
if os.path.exists(target_action_path) == False:
os.mkdir(target_action_path)
target_video_path = os.path.join(target_action_path,vid[i].split('.')[0])
if os.path.exists(target_video_path) == False:
os.mkdir(target_video_path)
print(video_path)
print(target_video_path)
run_RGB_copy(video_path,target_video_path)
Kinetics数据集下载及RGB帧提取介绍到这里,希望对大家能有所帮助!