JAFFE数据集
1998年发布,这是比较小和老的数据库。该数据库是由10位日本女性在实验环境下根据指示做出各种表情,再由照相机拍摄获取的人脸表情图像。整个数据库一共有213张图像,10个人,全部都是女性,每个人做出7种表情,这7种表情分别是sad、happy、angry、disgust、surprise、fear、neutral,每组大概20张样图。
该数据库包含213张由10位日本女模特构成的7种面部表情(6种基本面部表情+ 1个中性)的图像。每幅图片均由60位日本人对6种情感形容词进行了评级。图片为256x256灰度级,.tiff格式,无压缩。文本文件A_README_FIRST.txt中提供了平均超过60个主题的情感形容词的语义等级数据。
The Japanese Female Facial Expression (JAFFE) Database
JAFFE的处理
用haarcascade_frontalface_default.xml来做人脸检测并得到人脸候选框
def detect(img, cascade):
rects = cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30),flags=cv2.CASCADE_SCALE_IMAGE)
if len(rects) == 0:
return []
rects[:, 2:] += rects[:, :2]
return rects
cascade = cv2.CascadeClassifier("./haarcascade_frontalface_default.xml")
调整脸部区域的大小成48*48并得到表情的标签
f = "H:\emotion_dataset\JAFFE\deal_JAFFE\jaffedbase/"
fs = os.listdir(f)
data = np.zeros([213, 48*48], dtype=np.uint8)
label = np.zeros([213], dtype=int)
i = 0
for f1 in fs:
tmp_path = os.path.join(f, f1)
if not os.path.isdir(tmp_path):
# print(tmp_path[len(f):])
img = cv2.imread(tmp_path, 1)
dst = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rects = detect(dst, cascade)
for x1, y1, x2, y2 in rects:
cv2.rectangle(img,(x1+10,y1+20),(x2-10,y2),(0,255,255),2)
# 调整截取脸部区域大小
img_roi = np.uint8([y2-(y1+20), (x2-10)-(x1+10)])
roi = dst[y1+20:y2, x1+10:x2-10]
img_roi = roi
re_roi = cv2.resize(img_roi, (48,48))
# 获得表情label
img_label = tmp_path[len(f)+3:len(f)+5]
# print(img_label)
if img_label == 'AN':
label[i] = 0
elif img_label == 'DI':
label[i] = 1
elif img_label == 'FE':
label[i] = 2
elif img_label == 'HA':
label[i] = 3
elif img_label == 'SA':
label[i] = 4
elif img_label == 'SU':
label[i] = 5
elif img_label == 'NE':
label[i] = 6
else:
print("get label error.......\n")
data[i][0:48*48] = np.ndarray.flatten(re_roi)
i = i + 1
最后将该数据集存储为.csv格式
with open(r"./JAFFEface.csv","w") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['emotion', 'pixels'])
for i in range(len(label)):
data_list = list(data[i])
b = " ".join(str(x) for x in data_list)
l = np.hstack([label[i], b])
writer.writerow(l)
CK/CK+数据集处理
CK+数据库包括123个实验对象, 593 个 图片序列,每个图片序列的最后一张 图片都有动作单元的标签,而在这593个图片序列中,有327个序列有 情感标签。
进入网站后可以下载以下四个文件:
1)图片(cohn-kanade-images.zip)-123个对象中有593个序列,这些序列在峰帧处进行了FACS编码,所有序列都从中性面到峰值表达。
2)Landmarks(Landmarks.zip)-所有序列均经过AAM跟踪,每个图像带有68个地标点。
3)FACS编码文件(FACS_labels.zip)-对于每个序列(593),只有1个FACS文件,这是最后一帧(峰值帧)。文件的每一行对应一个特定的AU,然后对应一个强度。
4)情绪编码文件(Emotion_labels.zip)-593个序列中只有327个具有情绪序列,因为这些是唯一适合原型定义的参数。像FACS文件一样,每个序列只有1个Emotion文件,这是最后一帧(峰值帧)。只能有一个条目,数字范围为0-7(即0 =中立,1 =愤怒,2 =轻蔑,3 =厌恶,4 =恐惧,5 =快乐,6 =悲伤,7 =惊喜)。 N.B只有327个文件-如果没有文件,则意味着没有情感标签。
cohn-kanade-images.zip图片库中包含了从平静到表情表现峰值的图片,实际使用中建议使用比较明显的图片,并进行相应的预处理。
The Extended Cohn-Kanade Dataset(CK+)
若上述网站无法进入下载链接,这里是某好心博主的免费百度网盘链接
CK+的处理
裁剪人脸区域
def image_cut(file_name):
# cv2读取图片
im = cv2.imread(file_name)
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# cv2检测人脸中心区域
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.15,
minNeighbors=5,
minSize=(5, 5)
)
if len(faces) > 0:
for (x, y, w, h) in faces:
# PIL读取图片
img = Image.open(file_name)
# 转换为灰度图片
img = img.convert("L")
# 裁剪人脸核心部分
crop = img.crop((x, y, x + w, y + h))
# 缩小为120*120
crop = crop.resize((purpose_size, purpose_size))
return crop
return None
将图片转换为数据矩阵并且得到相应的表情标签
def image_to_matrix(filename):
# 裁剪并缩小
img = image_cut(filename)
data = img.getdata()
# 归一化到(0,1)
return np.array(data, dtype=float) / 255.0
def get_label(file_name):
f = open(file_name, 'r+')
line = f.readline() # only one row
line_data = line.split(' ')
label = float(line_data[3])
f.close()
# 1-7 的标签值转为 0-6
return int(label) - 1
保存脸部核心区域的数据到pickle文件中
def save_picture_data():
# like [[data1, label1], [data2, label2], ...]
data_label = []
# 获取子目录列表, like ['S005\001', 'S010\001', 'S010\002', ...]
dir_list = []
for root, dirs, _ in os.walk(image_dir):
for rdir in dirs:
for _, sub_dirs, _ in os.walk(root + '\\' + rdir):
for sub_dir in sub_dirs:
dir_list.append(rdir + '\\' + sub_dir)
break
break
# 遍历目录获取文件
for path in dir_list:
# 处理 images
for root, _, files in os.walk(image_dir + '\\' + path):
for i in range(0, len(files)):
if files[i].split('.')[1] == 'png':
# 裁剪图片,并将其转为数据矩阵
img_data = image_to_matrix(root + '\\' + files[i])
# 处理相应的 label
for lroot, _, lfiles in os.walk(label_dir + '\\' + path):
if len(lfiles) > 0: # picture has label
label = get_label(lroot + '\\' + lfiles[0])
data_label.append([img_data, label])
break
break
# 写入数据到pkl文件
pkl_file = '../data/data_label_list_120.pkl'
with open(pkl_file, 'wb') as f:
pickle.dump(data_label, f)
f.close()
print('Picture Data Saved Successfully into:', pkl_file)