就我们组所做的项目(人脸情绪识别)来说,本是可以不需要建立任何数据库的。但是本着追求进一步效率的想法,考虑到用于神经网络学习的CK+数据集的本身结构较为复杂,拥有比较复杂的文件结构,且体积也较大(接近2GB),不太方便输入到神经网络中进行训练,因此对此做了一个简单的数据库,用以将这个数据集的各个关键信息记录,从而在获取训练数据时,只要通过对数据库的SELECT操作即可获取,而不需要复杂的文件操作以及获取label的字符串处理等操作。
CK+数据集简介
In 2000, the Cohn-Kanade (CK) database was released for the purpose of promoting research into automatically detecting individual facial expressions. Since then, the CK database has become one of the most widely used test-beds for algorithm development and evaluation. During this period, three limitations have become apparent: 1) While AU codes are well validated, emotion labels are not, as they refer to what was requested rather than what was actually performed, 2) The lack of a common performance metric against which to evaluate new algorithms, and 3) Standard protocols for common databases have not emerged. As a consequence, the CK database has been used for both AU and emotion detection (even though labels for the latter havenotbeenvalidated),comparisonwithbenchmarkalgorithmsismissing, anduseofrandomsubsetsoftheoriginal database makes meta-analyses difficult. To address these andother concerns, we presenttheExtended Cohn-Kanade (CK+) database. The number of sequences is increased by 22%andthenumberofsubjectsby27%. Thetargetexpression for each sequence is fully FACS coded and emotion labels have been revised and validated. In addition to this, non-posed sequences for several types of smiles and their associated metadata have been added.
参照论文《The Extended Cohn-Kanade Dataset(CK+): A complete dataset for action unit and emotion-specified expression》
CK+数据集结构
分为四个文件夹:
1) The Images (cohn-kanade-images.zip) - there are 593 sequences across 123 subjects which are FACS coded at the peak frame. All sequences are from the neutral face to the peak expression.
2) The Landmarks (Landmarks.zip) - All sequences are AAM tracked with 68points landmarks for each image.
3) The FACS coded files (FACS_labels.zip) - for each sequence (593) there is only 1 FACS file, which is the last frame (the peak frame). Each line of the file corresponds to a specific AU and then the intensity. An example is given below.
4) The Emotion coded files (Emotion_labels.zip) - ONLY 327 of the 593 sequences have emotion sequences. This is because these are the only ones the fit the prototypic definition. Like the FACS files, there is only 1 Emotion file for each sequence which is the last frame (the peak frame). There should be only one entry and the number will range from 0-7 (i.e. 0=neutral, 1=anger, 2=contempt, 3=disgust, 4=fear, 5=happy, 6=sadness, 7=surprise). N.B there is only 327 files- IF THERE IS NO FILE IT MEANS THAT THERE IS NO EMOTION LABEL (sorry to be explicit but this will avoid confusion).
在目前阶段,我们暂时只考虑第一个和第四个文件夹。
对于第一个文件夹,包含123个文件夹,对应123个主体(Subject),即受试者,文件夹命名为S+主体编号。
对每个主体的文件夹,又包含若干个文件夹,每个文件夹对应一个表情序列,文件夹命名为序列编号,从001开始。
对于每个表情序列文件夹,包含若干张图片,展示主体从平静状态到表情峰值的变化过程中的图片序列,命名为S+主体编号_序列编号_图片编号,图片编号从00000001开始。
对于第二个文件夹,与第一个文件夹结构基本一致,但是到最里层的文件目录中不是图片,而是一个txt文件,命名为指定目录下对应的序列的最后一张图片的名称+emotion,该txt文件中包含一个值,从0到7不等,其中0=neutral, 1=anger, 2=contempt, 3=disgust, 4=fear, 5=happy, 6=sadness, 7=surprise。
数据库设计
数据库分为两个表Groups和Imgs。前者每个元组对应一个主体所做的一个表情序列的总和,后者每个元组对应一张图片。由于一个表情序列有多张图片,所以显然这是一个一对多的关系。
两个表的设计如下:
imgs
字段名 | 类型 | 注释 | 键 |
subject | smallint(6) | 主体 | 主键1,外键 |
group | tinyint(4) | 组号 | 主键2,外键 |
no | tinyint(4) | 图片编号 | 主键3 |
addr | varchar(255) | 图片路径 |
|
groups
字段名 | 类型 | 注释 | 键 |
subject | smallint(6) | 主体 | 主键1 |
group | tinyint(4) | 组号 | 主键2 |
emotion | tinyint(4) | 情绪编号 |
|
num | tinyint(4) | 组内图片总数 |
|
数据库导入
数据库建立完了,但是对于这超过一万张的图片,全部手动输入到数据库中是绝对不可能的,因此我写了一个Python的小脚本程序来代替我们执行数据库导入的操作。
1 import pymysql 2 import sys 3 import os 4 5 db = pymysql.connect('localhost', 'root', '123456', 'train') 6 cursor = db.cursor() 7 addr = 'H:\CK\cohn-kanade-images' 8 addr_e = 'H:\CK\Emotion' 9 for folder in os.listdir(addr): 10 addr2 = os.path.join(addr, folder) 11 for folder2 in os.listdir(addr2): 12 if not str(folder2)[0] == '.': 13 addr3 = os.path.join(addr2, folder2) 14 imgs = os.listdir(addr3) 15 num = len(imgs) 16 i = num - 1 17 while i != -1: 18 img = imgs[i] 19 img_name = img[: -4] 20 if img_name[0] == '.': 21 i -= 1 22 continue 23 print(img_name) 24 subject, group, no = (j for j in img_name.split('_')) 25 addr_p = os.path.join(addr3, img) 26 if i == num - 1: 27 addr_ans = os.path.join(addr_e, subject, group, subject 28 + '_' + group + '_' + no + '_emotion.txt') 29 try: 30 with open(addr_ans, 'r') as f: 31 ans = f.read().split('.')[0] 32 sql = """ 33 INSERT INTO `groups` VALUES(%s, %s, %s, %s) 34 """ % (subject[1:], group, ans, num) 35 print(subject[1:], group, ans, num) 36 try: 37 cursor.execute(sql) 38 db.commit() 39 except Exception as e: 40 print(e) 41 db.rollback() 42 except: 43 ans = '0' 44 sql = """ 45 INSERT INTO `groups` VALUES(%s, %s, %s, %s) 46 """ % (subject[1:], group, ans, num) 47 print(subject[1:], group, ans, num) 48 try: 49 cursor.execute(sql) 50 db.commit() 51 except Exception as e: 52 print(e) 53 db.rollback() 54 55 sql = """ 56 INSERT INTO imgs VALUES(%s, %s, %s, "%s"); 57 """ % (subject[1:], group, no, addr_p.replace('\\', '/')) 58 print(subject[1:], group, no, addr_p.replace('\\', '/')) 59 try: 60 cursor.execute(sql) 61 db.commit() 62 except Exception as e: 63 print(e) 64 db.rollback() 65 i -= 1
通过Python下的一系列文件操作和对文件名的字符串处理,再通过与MySQL的连接即可将这超过一万张图片的数据全部导入到指定数据库中。
导入结果如下:
导入完成后,我们要获取一张图片的地址以及其情绪类型,只需要通过以下语句:
db = pymysql.connect('localhost', 'root', '123456', 'train') cursor = db.cursor() sql = """select i.addr, g.emotion from imgs i, `groups` g where i.subject = g.subject and i.group = g.group;""" cursor.execute(sql) res = cursor.fetchone()
这样相比利用复杂的文件操作通过找文件的方式来获取训练数据要简化了相当多。