update 2022-10-22: 更新了LRW1000的官网链接详见史上最详细唇语识别数据集综述
本文将介绍唇语识别领域使用最多的几个数据集。
一、本文将详细的介绍数据集的格式以及处理方法,欢迎在评论区或私信讨论,博主将持续更新。
二、将全部分区文件下载后拼接解压即可得到完整数据集。
文章目录
0 分区文件拼接方法
针对数据集中的分区文件,LRW-1000,LRS2,LRS3等均可参考LRW数据集的解压方法。首先用cat命令拼接文件,之后用tar命令解压文件,即可得到完整数据集。linux直接使用即可,windows安装git bash再进行解压,可参考windows下Git BASH安装。进入分区文件所在的目录,使用此命令进行拼接(注意将名改为对应的数据集名)。
下图为官网关于LRW数据集解压方法的示例。
cat 数据集名前n-1个字母(最后一个用于排序) > 数据集名.tar
tar -xvf 数据集名
1 LRW
1.1 LRW 下载
MD5码
1.2 数据集格式
如图所示,格式为标准的分类任务数据集。
LRW/
LRW/EXAMPLE/
LRW/EXAMPLE/test/
LRW/EXAMPLE/test/EXAMPLE_00001.txt
1.3 数据集处理
LRW数据集经过人脸定位和预裁切,嘴唇区域位于视频正中心,一般会再次中心裁切出一个96×96的区域,转换为灰度图,npz存储或pkl存储均可。LRW提供每一个样本的属性,记录在对应的txt文件中,有用的是最后一行duration属性,可依据此推断出word boundary,可参考以下代码:
def load_duration(self, file):
with open(file, 'r') as f:
lines = f.readlines()
for line in lines:
if line.find('Duration') != -1:
duration = float(line.split(' ')[1])
tensor = np.zeros(29)
mid = 29 / 2
start = int(mid - duration / 2 * 25)
end = int(mid + duration / 2 * 25)
tensor[start:end] = 1.0
return tensor
2 LRW-1000
2.1 数据集格式
LRW-1000/
LRW-1000/audio/
LRW-1000/image/
LRW-1000/image/0003529debd6745763c7b6dbfff9b4d3/
LRW-1000/Data_Annotation.txt
LRW-1000/info/
LRW-1000/info/length/
LRW-1000/info/length/tst_1000_length_easy.txt
LRW-1000/info/resolution/
LRW-1000/info/resolution/tst_1000_resolution_easy.txt
LRW-1000/info/yaw/
LRW-1000/info/yaw/tst_1000_yaw_easy.txt
LRW-1000/info/all_audio_video.txt
LRW-1000/info/tst_1000.txt
3 LRS2
3.1 LRS2下载
MD5码(Filelist的值不同,因为是复制粘贴保存的)
3.2 数据集格式
LRS2/
LRS2/main/
LRS2/main/5535415699068794046/
LRS2/main/5535415699068794046/00001
LRS2/pretrain/
LRS2/pretrain/5535415699068794046/
LRS2/pretrain/5535415699068794046/00001
4 LRS3-TED
4.1 LRS3-TED下载
MD5码
4.2 数据集格式
参考LRS2数据集,train不提供单词的起止时间
5 OuluVS2
5.1 数据集格式
按speaker分成52个压缩包
OuluVS2/
包含这个说话者的所有样本,s表示speaker,v表示view,u表示utter
OuluVS2/orig_orgs01/
5.2 数据集处理
OuluVS2数据集转换为LRW分类格式的python代码,将所有压缩包解压到source_root中,如图:
使用此代码进行文件提取及重组,得到与LRW数据集格式相同的OuluVS2数据集。
import glob
from shutil import copyfile
import os
source_root = r"E:\DL\dataset\lipreading\OuluVS2\raw_unzip"
target_root = r"E:\DL\dataset\lipreading\OuluVS2\raw_LRW_format"
all_test = [6, 8, 9, 15, 26, 30, 34, 43, 44, 49, 51, 52]
files = glob.glob(source_root + "\\*\\*\\*")
files = [i for i in files if "v1" in i]
print(len(files))
k = []
for j in files:
for i in range(31, 61):
if "u" + str(i) in j:
k.append(j)
train_list = []
test_list = []
for i in k:
flag = False
for j in all_test:
if "s" + str(j) in i:
test_list.append(i)
flag = True
if not flag:
train_list.append(i)
print(len(train_list), len(test_list))
for i in train_list:
file_name = i.split("\\")[-1].split(".")[0].split("_")
class_number = (int(file_name[-1][1:]) - 31) // 3
# print(class_number)
save_name = target_root + "\\" + str(class_number) + "\\train\\" + i.split("\\")[-1]
# print(save_name)
if not os.path.exists("\\".join(save_name.split("\\")[:-1])):
os.makedirs("\\".join(save_name.split("\\")[:-1]))
copyfile(i, save_name)
print(i)
for i in test_list:
file_name = i.split("\\")[-1].split(".")[0].split("_")
class_number = (int(file_name[-1][1:]) - 31) // 3
# print(class_number)
save_name = target_root + "\\" + str(class_number) + "\\test\\" + i.split("\\")[-1]
# print(save_name)
if not os.path.exists("\\".join(save_name.split("\\")[:-1])):
os.makedirs("\\".join(save_name.split("\\")[:-1]))
copyfile(i, save_name)
print(i)
for i in test_list:
file_name = i.split("\\")[-1].split(".")[0].split("_")
class_number = (int(file_name[-1][1:]) - 31) // 3
# print(class_number)
save_name = target_root + "\\" + str(class_number) + "\\val\\" + i.split("\\")[-1]
# print(save_name)
if not os.path.exists("\\".join(save_name.split("\\")[:-1])):
os.makedirs("\\".join(save_name.split("\\")[:-1]))
copyfile(i, save_name)
print(i)