github代码:https://github.com/adithyaselv/face-expression-detect
原理
人脸表情分类,将人脸表情分为7类,
emotions={ 1:"Anger", 2:"Contempt", 3:"Disgust", 4:"Fear", 5:"Happy", 6:"Sadness", 7:"Surprise"}
分类原理为,首先采用dlib检测人脸的68个特征点,根据特征点提取人脸特征向量,之后采用pca对特征向量进行降维最后采用SVM对输入特征向量进行分类.
根据特征点提取人脸特征向量,
features=generateFeatures(landmarks)
得到一个26565维的特征向量后,采用pca进行降维,得到一个75维的特征向量
print "Performing PCA Transform......."
pca_features=pca.transform(features)
之后将75维的特征向量输入SVM进行分类(这里分为)
根据人脸23个的特征点,将这些点每4个组合成一个子序列,这样得到8855中组合.
keyPoints = [18, 22, 23, 27, 37, 40, 43, 46, 28, 32, 34,
36, 5, 9, 13, 49, 55, 52, 58,61,63,65,67]
combinations = itertools.combinations(keyPoints, 4)#将keyPonints中的所有元素组合成四个元素的子序列,这样有C23^4=8855种组合
对于每个子序列,按照三种方式重新排序,这样得到 8855×3=26565 种特征点组合.
pointIndices1 = []
pointIndices2 = []
pointIndices3 = []
pointIndices4 = []#26565
for combination in combinations:
pointIndices1.append(combination[0])
pointIndices2.append(combination[1])
pointIndices3.append(combination[2])
pointIndices4.append(combination[3])
pointIndices1.append(combination[0])
pointIndices2.append(combination[2])
pointIndices3.append(combination[1])
pointIndices4.append(combination[3])
pointIndices1.append(combination[0])
pointIndices2.append(combination[3])
pointIndices3.append(combination[1])
pointIndices4.append(combination[2])
根据得到的4组坐标点索引组合,分别为pointIndices1, pointIndices2, pointIndices3, pointIndices4,每个组合长度为26565.根据坐标点索引,计算特征点的位置坐标x,y值. 最后根据每两个坐标点之间的欧式距离之比计算特征向量:
Features = numpy.zeros((1, len(pointIndices1)))
ratios = [];
for i in range(0, len(pointIndices1)):
x1 = landmarkCoordinates[2*(pointIndices1[i]-1)]
y1 = landmarkCoordinates[2*pointIndices1[i] - 1]
x2 = landmarkCoordinates[2*(pointIndices2[i]-1)]
y2 = landmarkCoordinates[2*pointIndices2[i] - 1]
x3 = landmarkCoordinates[2*(pointIndices3[i]-1)]
y3 = landmarkCoordinates[2*pointIndices3[i] - 1]
x4 = landmarkCoordinates[2*(pointIndices4[i]-1)]
y4 = landmarkCoordinates[2*pointIndices4[i] - 1]
points = [x1, y1, x2, y2, x3, y3, x4, y4]
ratios.append(findRatio(points))#计算x1,y1与x2,y2的欧式距离d1,计算x3,y3与x4,y4的欧式距离d2,ration=d1/d2
Features = numpy.asarray(ratios)#26565
return Features
计算特征值:
def findRatio(points):
''' Function to find ratios '''
x=[0]*4
y=[0]*4
for i in range(4):
x[i]=points[(2*i)]
y[i]=points[(2*i)+1]
dist1 = math.sqrt((x[0]-x[1])**2 + (y[0]-y[1])**2)
dist2 = math.sqrt((x[2]-x[3])**2 + (y[2]-y[3])**2)
ratio = dist1/dist2
return ratio
模型训练
由上面分析可知,我们需要训练的有PCA, SVM两个模型.
训练数据,下载包括四个文件夹,
/media/qinghua/文档/data/data_image/ck/cohn-kanade-images,人脸表情图像.
/media/qinghua/文档/data/data_image/ck/Landmarks,为每张图像的特征点坐标x,y.
/media/qinghua/文档/data/data_image/ck/Emotion,保存了每张图像对应的表情标签,分别为1-7范围内的值,
保存为文本文件,文件名为图像名.