CNN表情识别系统制作(1)----fer2013人脸表情数据集简介

fer2013人脸表情数据集简介

fer2013人脸表情数据集由35886张人脸表情图片组成,其中,测试图(Training)28708张,公共验证图(PublicTest)和私有验证图(PrivateTest)各3589张,每张图片是由大小固定为48×48的灰度图像组成,共有7种表情,分别对应于数字标签0-6,具体表情对应的标签和中英文如下:0 anger 生气; 1 disgust 厌恶; 2 fear 恐惧; 3 happy 开心; 4 sad 伤心;5 surprised 惊讶; 6 normal 中性。

但是,数据集并没有直接给出图片,而是将表情、图片数据、用途的数据保存到csv文件中,如下图所示,

在这里插入图片描述

如上图所示,第一张图是csv文件的开头,第一行是表头,说明每列数据的含义,第一列表示表情标签,第二列即为图片数据,这里是原始的图片数据,最后一列为用途。

将表情图片提取出来

知道数据结构以后,就好办了,使用pandas解析csv文件,再将原始图片数据保存为jpg文件,并根据用途和标签标签进行分类,分别保存到对应文件夹下,代码比较简单,并且做了详细备注,直接给完整代码如下:

import cv2
# pip install opencv-python -i https://mirrors.aliyun.com/pypi/simple/
import pandas as pd
import numpy as np
import os


emotions = {
    '0': 'anger',  # 生气
    '1': 'disgust',  # 厌恶
    '2': 'fear',  # 恐惧
    '3': 'happy',  # 开心
    '4': 'sad',  # 伤心
    '5': 'surprised',  # 惊讶
    '6': 'normal',  # 中性
}
#创建文件夹
def createDir(dir):
    if os.path.exists(dir) == False:
        os.makedirs(dir)
createDir("../imgs")
def saveImageFromFer2013(file):
    #读取csv文件
    faces_data = pd.read_csv(file)
    # print(faces_data.head(10))
    # print(faces_data.columns) #['emotion', 'pixels', 'Usage']
    # print(faces_data.shape)(35887, 3)
    # print(len(faces_data)) # 35887
    #遍历csv文件内容,并将图片数据按分类保存
    print(faces_data.head())
    for index in range(len(faces_data)):
        #解析每一行csv文件内容
        emotion_data = faces_data.iloc[index, 0]
        # print(emotion_data)
        image_data = faces_data.iloc[index, 1]
        # print(image_data)
        # print(type(image_data))
        usage_data = faces_data.iloc[index, 2]

        #  ['222', '222', '210'] 变成[222, 222, 210]
        data = list(map(float, image_data.split()))
        #将图片数据转换成48*48
        image = np.array(data).reshape(48, 48)
        print(image.shape)
        #选择分类,并创建文件名
        dirName = usage_data
        emotionName = emotions[str(emotion_data)]
        # print(emotionName)
        #图片要保存的文件夹
        image_path = os.path.join(dirName, emotionName)
        print(image_path)
        # 创建“用途文件夹”和“表情”文件夹
        createDir(image_path)
        #图片文件名
        image_Name = os.path.join(image_path, str(index) + '.jpg')
        cv2.imwrite(image_Name, image)  #使用cv2实现图片与numpy数组的相互转化


saveImageFromFer2013('../datasets/fer2013/fer2013.csv')

运行结果,

image

运行完上面的代码后,得到3个文件夹,文件下有相应的表情的子文件夹,

在这里插入图片描述

子文件夹下又有相应的图片,

在这里插入图片描述

加载fer2013数据集合

创建 utils.py

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

def load_data(data_file):
    """ loads fer2013.csv dataset
        # Arguments: data_file fer2013.csv
        # Returns: faces and emotions
                faces: shape (35887,48,48,1)
                emotions: are one-hot-encoded
    """
    data = pd.read_csv(data_file)
    print(data.head())
    pixels = data['pixels'].to_list()
    weight, height = 48, 48
    faces = []
    for pixel_squence in pixels:
        face = [int(pixel) for pixel in  pixel_squence.split()]
        face = np.array(face).reshape(weight, height)
        faces.append(face)
    faces = np.array(faces)
    ## 扩充一个维度
    faces = np.expand_dims(faces,-1)
    # 获取该列的one_hot表示
    df = pd.get_dummies(data['emotion'])
    emotions = df.values
    return faces, emotions
def preprocess_input(images):
    "归一化数据"
    images = images/255
    return images

faces, emotions = load_data('../datasets/fer2013/fer2013.csv')
print('faces.shape = ', faces.shape)
print('emotions.shape = ', emotions.shape)
print("faces[0].shape = ", faces[0].shape) # 一张表情图
one_face = faces[0].reshape(48, -1)
print('one_face.shape = ', one_face.shape)
one_emotion = emotions[0]
print('one_emotion = ', one_emotion)
plt.imshow(one_face, cmap='gray')
plt.show()

print(preprocess_input(one_face))



该函数输入的是fer2013.csv文件路径,返回值是一个元组,包含faces图像矩阵以及emotions的one-hot-encoded矩阵。
data = pd.read_csv(data_file)
利用pandas读取csv文件到data变量。
pixels = data[‘pixels’].tolist() 返回一个列表,列表中每个数据如下:

70 80 82 72 58 58 60 63 54 58 60 48 89 115 121 119 115 110 98 91 84 84 90 99 110 126 143 153 158 171 169 172 169 165 129 110 113 107 95 79 66 62 56 57 61 52 43 41 65 61 58 57 56 69 75 70 65 56 54 105 146 154 151 151 155 ...

列表中每个数据都是表情图片像素点的值的集合,用空格分隔。

接下来,遍历图像列表,

faces = []
for pixel_squence in pixels:
    face = [int(pixel) for pixel in  pixel_squence.split()]
    face = np.array(face).reshape(weight, height)
    faces.append(face)

遍历图像列表,将每一个图片像素数据先用空格分隔,然后转换为列表,之后在转换为48*48的矩阵,最后加入到列表faces。

faces = np.array(faces)

将列表faces再次转换成numpy矩阵,此时faces的shape为(35887,48,48)

faces = np.expand_dims(faces,-1)

扩充faces的维度,扩充之后的faces的shape为(35887,48,48,1),做此步操作的原因是,神经网络的输入为图片,格式为(height,width,通道信息)。

df = pd.get_dummies(data['emotion'])

pd.get_dummies(data[‘emotion’])获得每一个表情分类的one-hot表示,返回的是一个dataframe,最后调用

emotions = df.values

将类型转换为矩阵

在这里插入图片描述

在这里插入图片描述

  • 8
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,以下是使用fer2013数据集CNN模型进行人脸表情识别的Python代码: ```python import pandas as pd import numpy as np import keras from keras.utils import np_utils from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense # 加载数据集 data = pd.read_csv('/path/to/fer2013.csv') # 将像素值转换为图像 pixels = data['pixels'].tolist() images = [] for pixel_sequence in pixels: image = [int(pixel) for pixel in pixel_sequence.split(' ')] image = np.asarray(image).reshape(48, 48) images.append(image) images = np.asarray(images) images = np.expand_dims(images, -1) # 将标签转换为独热编码 labels = np_utils.to_categorical(data['emotion']) # 划分训练集、验证集和测试集 train_images, val_images, test_images = images[:25000], images[25000:30000], images[30000:] train_labels, val_labels, test_labels = labels[:25000], labels[25000:30000], labels[30000:] # 构建CNN模型 model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(48, 48, 1))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Conv2D(128, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(128, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(1024, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(7, activation='softmax')) # 编译模型 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # 训练模型 model.fit(train_images, train_labels, batch_size=64, epochs=50, validation_data=(val_images, val_labels)) # 在测试集上评估模型 score = model.evaluate(test_images, test_labels, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ``` 这个代码使用了Keras库来构建CNN模型。首先,我们将fer2013数据集加载到Pandas DataFrame中,并将像素值转换为图像。然后,我们将标签转换为独热编码,并将数据集划分为训练集、验证集和测试集。接下来,我们构建CNN模型,并编译它。最后,我们在训练集和验证集上训练模型,并在测试集上评估模型的性能。 请注意,这只是一个简单的示例代码,您可以根据需要进行修改和优化。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值