赞
踩
翻翻存货后,给大家分享下一个小小的项目。
完整源码可点赞关注后评论留下邮箱。
本实验利用支持向量机对人脸情感特征进行训练,对模型进行封装,使得后续可直接调用模型进行人脸情感分类,并将表情识别运用到实际场景中,将其与现实需求进行良好结合。
一、实验步骤
(1) 数据收集
下载The Extended Cohn-Kanade Dataset(CK+)数据集,这个数据库是在 Cohn-Kanade Dataset 的基础上扩展来的,发布于2010年。这个数据库比起JAFFE等人脸情感数据集要大的多,而且也可以免费获取。
(2) 数据预处理
将下载好的CK+数据集的图片进行分类,并对图片进行裁剪。分别保存在对应的八个文件夹下,并以标签名命名该文件夹。
最终一共整理了973张图片用于本次项目的训练及测试,分类比例较为平衡,平均每个分类有122张图片。
(3) 特征提取
目前人脸情感特征提取方法主要分为光流法、模型法和几何法。
在表情特征提取方法中,研究者考虑到表情的产生与表达在很大程度上是依靠面部器官的变化来反映的。人脸的主要器官及其褶皱部分都会成为表情特征集中的区域。因此在面部器官区域标记特征点,计算特征点之间的距离和特征点所在曲线的曲率,就成为了采用几何形式提取人脸表情的方法。使用形变网格对不同表情的人脸进行网格化表示,将第一帧与该序列表情最大帧之间的网格节点坐标变化作为几何特征,实现对表情的识别。
(4) 建立和封装模型
将数据集随机打乱,并以7:3的比例分为训练集和测试集。
建立模型:通过调用scikit-learn中的svm建立模型,训练先前得到的特征及其对应标签。
封装:调用joblib模块中的dump方法对模型进行封装。
二、具体实验步骤
(1) 数据预处理
将下载好的CK+数据集的图片进行分类,并对图片进行裁剪。分别保存在对应的八个文件夹下,并以标签名命名该文件夹。
八个类别分别为:生气(anger),蔑视(contempt),憎恨(disgust),害怕(fear),开心(happy),中性(neutral),悲伤(sadness),惊喜(surprise)。而数据预处理如下:
这张是数据预处理前的人脸情感图片:
数据预处理完成后的图片如下:
我们通过使用平滑,灰度变换,对比度调整等技术手段,对图片进行了相应的处理,最终只保留了每张图片的脸部情感部分。
具体代码如下:
import dlib
import cv2
import numpy as np
from PIL import Image
import PIL
import os
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(
"E:/shape_predictor_68_face_landmarks.dat")
def resize(image,resize_img):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe_image = clahe.apply(gray)
detections = detector(clahe_image, 1)
for k, d in enumerate(detections): # 迭代检测到的所有人脸
shape = predictor(clahe_image, d) # 用predictor类绘制面部地标
xlist = []
ylist = []
landmarks = []
for i in range(0, 68): # 将x、y坐标存入xlist、ylist里。
cv2.circle(clahe_image, (shape.part(i).x, shape.part(i).y), 1, (0, 0, 255), thickness=2)
xlist.append(float(shape.part(i).x))
ylist.append(float(shape.part(i).y))
xmean = np.mean(xlist)
ymean = np.mean(ylist)
x_max = np.max(xlist)
x_min = np.min(xlist)
y_max = np.max(ylist)
y_min = np.min(ylist)
cv2.rectangle(clahe_image, (int(x_min), int(y_min - ((ymean - y_min) / 3))), (int(x_max), int(y_max)),
(255, 150, 0), 2)
cv2.circle(clahe_image, (int(xmean), int(ymean)), 1, (0, 255, 255), thickness=2)
x_start = int(x_min)
y_start = int(y_min - ((ymean - y_min) / 3))
w = int(x_max) - x_start
h = int(y_max) - y_start
crop_img = image[y_start:y_start + h, x_start:x_start + w]
if len(detections) > 0:
mywidth = 48
hsize = 48
cv2.imwrite('crop_img.png', crop_img)
img = Image.open('crop_img.png')
img = img.resize((mywidth, hsize), PIL.Image.ANTIALIAS)
img.save(resize_img)
if __name__ == '__main__':
path = r'E:\CK+\neutral/' # 未裁剪的图片路径
path2 = r'E:\CK+\neutral2/' # 裁剪后保存图片的路径
for root, dir, files in os.walk(path):
for file in files:
print(file)
img = cv2.imread(path+file)
resize(img,path2+file)
最终我们一共整理了973张图片用于本次项目的训练及测试,分类比例较为平衡,平均每个分类有122张图片。
(2) 结果分析
模型评估效果如下:
不难发现的是,该模型的总体准确率较高,其中surprise类别的数据集的准确率甚至高达100%,但其中neutral、anger以及happy的准确率偏低,低于90%。
在分析讨论之后,我认为是这几种情感时的人脸特征较为接近,导致模型训练时出现了学习偏差,分类效果下降,且同理,由于惊讶时的特征较为突出,易于模型的训练学习,所以分类时的效果会高得多。
(3) 图形界面运行展示
为方便调用模型进行人脸情感分类,我利用python编写了一个简易的图形界面,具体使用如下图所示:
结束语
对人脸情感分类感兴趣的或者对图像处理+机器学习想入门的朋友,可以拿这个项目练练手,简单但学到的东西也不少。
个人认为以上的准确率完全有提高的手段,如增加训练数据量、增加所提取的AU种类等,应该在一定程度上有所帮助。
另外,需要源码的朋友可以关注点赞收藏,并留下你的邮箱,我会第一时间发送给你,同时也希望大家尊重本人的创作呀,共勉!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。