人脸表情识别数据集:CK+

  1. CK+有123的子类(人),每个人提供1~7种表情,每种表情是一组序列(总共有593个图像序列,其中327个序列是有表情标签的):从自然缓慢变化到给定表情

在这里插入图片描述
比如上图是人S026做出的某类表情,第一张是自然,缓慢变化到最终是峰值快乐表情

  1. 标签
    593个序列中只有327个是具有情感序列标签的,情绪类别分别是0=neutral, 1=anger, 2=contempt, 3=disgust, 4=fear, 5=happy, 6=sadness, 7=surprise

某些实验会说明在CK+上的精度,所以需要自己制作为ImageNet式的数据集

import glob
import os
import shutil
import cv2


def creat_folder():
    [os.makedirs(os.path.join('results',folder,str(i+1))) for folder in ['ckp','ckp_facedet_crop','train','val','test'] for i in range(7)]


def toImageFolder():
    """
    将该函数所在脚本与"Emotion_labels"和"extended-cohn-kanade-images"同级,
    成功运行后,会产生ckp文件夹并有1~7共7个子文件夹,总共981张图片(选取最后三张)
    @return:
    """
    i = 0
    for info in os.walk("Emotion_labels/Emotion"):
        abs_path, _, file_names = info  # 获取标签文件所在路径,以及标签文件的名字file_names
        if file_names.__len__() > 0:  # 如果至少存在一个标签,则循环读取标签复制相应图片文件
            for file_name in file_names:
                # 获取当前标签的类别
                with open(os.path.join(abs_path, file_name)) as f:
                    label_context = f.readline()
                    label_index = label_context.strip()[0]
                # 标签仅记录序列图片中感情最强烈的图片[pos=-1],但是倒数几张[pos=-1,-2,-3]其实都很强烈,可以作为数据集
                img_root_path = abs_path.replace("Emotion_labels/Emotion",
                                                 "extended-cohn-kanade-images/cohn-kanade-images")
                img_paths = glob.glob(img_root_path + "/*")
                for img_path in img_paths[-3:]:  # 选取最后三张
                    # 将label路径修改为"xx/类别/文件名"路径
                    src = img_path
                    dst = os.path.join('results',"ckp", label_index,
                                       img_path.split(os.path.sep)[-1])  # eg: 'ckp\\3\\S005_001_00000009.png'
                    shutil.copyfile(src, dst)
                    i += 1
    print("图片总数:", i)


def face_crop():
    """
    遍历ckp每个子文件夹下的所有图片,进行人脸检测并裁剪
    @return:
    """
    def face_detect(img_path):
        image = cv2.imread(img_path)
        image_draw = image.copy()
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
        faces = face_detector.detectMultiScale(gray, 1.02, 20)
        for x, y, w, h in faces:
            face_img = image[y:y + h, x:x + w]
            cv2.rectangle(image_draw, (x, y), (x + w, y + h), (0, 0, 255), 2)
        dst = img_path.replace("ckp", 'ckp_facedet_crop')
        # 需要创建文件夹
        cv2.imwrite(dst, face_img)

    i = 0
    for sub in glob.glob("results/ckp/*"):
        for img_path in glob.glob(sub + "/*"):
            face_detect(img_path)
            i += 1
            if i % 50 == 0:
                print(i)

def cp_splite_img():
    """
    根据同级的train_list.txt、val_list.txt、test_list.txt,
    分割文件我用PaddleX GUI划分,也可以手动划分
    按ImageNet式数据集划分标签进行train、val和test划分
    @return:
    """
    def cp_train_data():
        """
        读取train_list.txt文件,并将所属train数据复制到train文件夹内
        @return:
        """
        with open("train_list.txt") as f:
            file_datas=f.readlines()
            for data in file_datas:
                path,index=data.split(" ")
                src = os.path.join('results','ckp_facedet_crop', path)
                dst=os.path.join('results',"train",path)
                shutil.copyfile(src,dst)

    def cp_val_data():
        with open("val_list.txt") as f:
            file_datas=f.readlines()
            for data in file_datas:
                path,index=data.split(" ")
                src = os.path.join('results','ckp_facedet_crop', path)
                dst=os.path.join('results',"val",path)
                shutil.copy(src,dst)

    def cp_test_data():
        with open("test_list.txt") as f:
            file_datas=f.readlines()
            for data in file_datas:
                path,index=data.split(" ")
                src = os.path.join('results','ckp_facedet_crop', path)
                dst=os.path.join('results',"test",path)
                shutil.copy(src,dst)

    cp_train_data()
    cp_val_data()
    cp_test_data()

if __name__=="__main__":
    """
    同级目录下,应当包含:
        Emotion_labels:CK+标签文件夹
        extended-cohn-kanade-images:CK+图像文件夹
        ck+process.py:本程序
        haarcascade_frontalface_default.xml:opencv人脸检测器
        test_list.txt:分割列表
        train_list:分割列表
        val_list:分割列表
    """
    print("创建文件夹......")
    creat_folder()
    print("开始处理ImageFolder......")
    toImageFolder()  # 将原始CK+整理为ImageFolder形式,复制到ckp文件夹
    print("开始处理人脸检测裁剪......,裁剪后请手动处理裁剪失败的样本")
    face_crop() # 遍历ckp文件夹所有图像进行人脸检测裁剪,$少许裁剪失败,需手动修复
    print("开始train、val和test划分......")
    cp_splite_img()  # 根据同级的train_list.txt、val_list.txt、test_list.txt,进行train、val和test划分

猜你喜欢

转载自blog.csdn.net/qq_40243750/article/details/128019629
今日推荐