基于Dlib库的人脸表情分析与识别——Python

基于Dlib库的⼈脸表情分析与识别——Python
本项⽬主要由包含我在内的四名成员共同完成:孙明喆、吴震、张晨、张明
项⽬介绍,及可执⾏⽂件、模型⽂件、详细报告均在GitHub中可以查看:
关于项⽬的详细介绍,可能过些⽇⼦在复习时候会有所补充
2020年2⽉28⽇更新
⽂章⽬录
⼀、引⾔
⼈脸表情是⼈们之间⾮语⾔交流时的最丰富的资源和最容易表达⼈们感情的⼀种有效⽅式,在⼈们的交流中起着⾮常重要的作⽤。表情含有丰富的⼈体⾏为信息,是情感的主载体,通过脸部表情能够表达⼈的微妙的情绪反应以及⼈类对应的⼼理状态,由此可见表情信息在⼈与⼈之间交流中的重要性。⼈脸表情识别技术随着⼈们对表情信息的⽇益重视⽽受到关注,成为⽬前-个研究的热点。所谓⼈脸表情识别,就是利⽤计算机进⾏⼈脸表情图像获取、表情图像预处理、表情特征提取和表情分类的过程,它通过计算机分析⼈的表情信息,从⽽推断⼈的⼼理状态,最后达到实现⼈机之间的智能交互。表情识别技术是
情感计算机研究的内容之⼀,是⼼理学、⽣理学、计算机视觉、⽣物特征识别、情感计算、⼈⼯⼼理理论等多学科交叉的⼀个极富挑战性的课题,它的研究对于⾃然和谐的⼈机交互、远程教育、安全驾:驶等都有重要的作⽤和意义。
⼆、关键技术
2.1 基于⼏何特征提取的⽅法
2.1.1 原理介绍
基于⼏何特征的表情识别是指对嘴、眉⽑、⿐⼦、眼睛等这些⼈脸表情的显著特征的形状和位置变化进⾏定位和测量,确定它的形状、⼤⼩、距离及相互⽐例,进⾏表情识别的⽅法。Bourel 等⼈定义了⾯部特征点之间的九个距离并通过它们构建了表情特征向量进⾏表情分析。Chibelushi 等⼈也采⽤了⾯部⼏何特征点并采⽤Kanade-Tucas-Tomasi 特征点跟踪算法实现特征点跟踪,然后通过计算得到九个特征系数,⽽这九个系数构成了特征流,描述了由于表情的发⽣⽽引起的⾯部特征点的⼏何关系的变化。Pantic 等⼈进⾏⾯部特征检测并确定⾯部⼏何关系,然后他们通过规则推理系统将这种⾯部⼏何关系转化为⾯部动作单元的活动,最终通过专家系统实现表情识别。Ying-li Tian等 ⼈采⽤⼏何特征提取与神经⽹络相结合的⽅法对正⾯或接近正⾯的⾯部图像进⾏表情识别,其中提取⼏何特征主要包括对于关键部位的定位特征和表情区的形状特征。
2.1.2 实现⽅法
实例化⼀个 shape_predictor 对象,使⽤dlib训练好⼈脸特征检测器,进⾏⼈脸的特征点标定。标定的时候使⽤opencv的circle⽅法,在特征点的坐标上⾯添加⽔印,内容就是特征点的序号和位置。
2.2 机器学习的过程
机器学习⽅法是计算机利⽤已有的数据(经验),得出了某种模型(迟到的规律),并利⽤此模型预测未来(是否迟到)的⼀种⽅法。从⼴义上来说,机器学习是⼀种能够赋予机器学习的能⼒以此让它完成直接编程⽆法完成的功能的⽅法。但从实践的意义上来说,机器学习是⼀种通过利⽤数据,训练出模型,然后使⽤模型预测的⼀种⽅法。
2.3 分类器的选择及设计
2.2.1 KNN分类原理介绍
分类器采⽤KNN分类,K近邻算法(K-NN)算法是⼀种简单但也很常⽤的分类算法,它也可以应⽤于回归计算。K-NN是⽆参数学习,这意味着它不会对底层数据的分布做出任何假设。它是基于实例,即该算法没有显式地学习模型。相反,它选择的是记忆训练实例,并在⼀个有监督的学习环境中使⽤。KNN算法的实现过程主要包括距离计算⽅式的选择、k值得选取以及分类的决策规则三部分。
2.2.2 KNN分类的决策规则大脑肥胖症
常⽤的分类决策规则是取k个近邻训练数据中类别出现次数最多者作为输⼊新实例的类别。即⾸先确定前k个点所在类别的出现频率,对于离散分类,返回前k个点出现频率最多的类别作预测分类;对于回归则返回前k个点的加权值作为预测值。
2.2.3 Sklearn库实现KNN分类器的⽅法
划分相应的训练集与测试集,调⽤sklearn库中的ighbors,#创建knn类 :knn = KNeighborsClassifier(),#训练knn
:Knn.fit(X_train,y_train)
三、设计⽅案及步骤
3.1总体⽅案设计
利⽤Dlib库进⾏⼈脸识别与特征标定,结合嘴、眉⽑、⿐⼦、眼睛这些⼈脸表情的显著特征的形状和位置变化进⾏定位和测量,确定它的形状、⼤⼩、距离及相互⽐例,进⾏表情识别。利⽤sklearn库中机器学习的算法对特征值进⾏学习分类。利⽤cv2库进⾏摄像头视频的采集,以及标定点位置。利⽤pygame库实现⾳频的播放等。利⽤numpy库对数组进⾏操作。
3.2详细⽅案设计
3.2.1利⽤dlib进⾏⼈脸识别
# 使⽤特征提取器get_frontal_face_detector
detector = _frontal_face_detector()
# dlib的68点模型,使⽤作者训练好的特征预测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
桥梁博士
# 利⽤预测器预测
shape = predictor(img, d)
# 标出68个点的位置
for i in range(68):
cv2.circle(img,(shape.part(i).x, shape.part(i).y),4,(0,255,0),-1,8)
cv2.putText(img,str(i),(shape.part(i).x, shape.part(i).y), cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255))
3.2.2 数据集的采集与建⽴(特征提取)
本⽂选择的The Extended Cohn-Kanade Dataset(CK+)表情数据库。这个数据库包括123个subjects, 593 个 image sequence,每个image sequence的最后⼀张 Frame 都有action units 的label,⽽在这593个image sequence中,有327个sequence 有 emotion的label。是数据库是⼈脸表情识别中⽐较流⾏的⼀个数据库。该⼈脸数据库包括七个表情类分别是0-中性、1-愤怒、2-蔑视、3-厌恶、4-恐惧、5-⾼兴、6-悲伤、7-惊讶,遍历每个表情类提取每个表情类每张图⽚的⼈脸特征值,。本⽂采⽤五维特征值分别是a-嘴巴宽度与识别框宽度之⽐、b-嘴巴⾼度与识别框⾼度之⽐、c-眉⽑⾼度与识别框⾼度之⽐、d-眉⽑距离与识别框宽度之⽐、e-眼睛睁开距离与识别框⾼度之⽐。将提取的五维特征值按表情类保存为xls表格,并为表情数据集打标签,以便后续训练分类识别模型使⽤。
#使⽤workbook⽅法,创建⼀个新的⼯作簿
book = xlwt.Workbook(encoding='utf-8', style_compression=0)
#添加⼀个sheet,名字为mysheet
sheet = book.add_sheet('mysheet', cell_overwrite_ok=True)溧阳地震
#遍历每张图⽚提取图⽚中⼈脸的特征值
for m in range():
path =str(m)+'.jpg'
print(path)
im_rd = cv2.imread(path)
im_rd = size(im_rd ,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC)
n =0
k = cv2.waitKey(1)在显像管的电子中
img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)
# 使⽤⼈脸检测器检测每⼀帧图像中的⼈脸。并返回⼈脸数rects
faces = self.detector(img_gray,0)
# 待会要显⽰在屏幕上的字体
font = cv2.FONT_HERSHEY_SIMPLEX
# 如果检测到⼈脸
if(len(faces)!=0):
# 对每个⼈脸都标出68个特征点
for i in range(len(faces)):
for i in range(len(faces)):
# enumerate⽅法同时返回数据对象的索引和数据,k为索引,d为faces中的对象
for k, d in enumerate(faces):
# ⽤红⾊矩形框出⼈脸
# 计算⼈脸热别框边长
self.face_width = d.right()- d.left()
灭火器的维修与报废#self.face_hight = d.bottom() - d.top()
# 使⽤预测器得到68点数据的坐标
shape = self.predictor(im_rd, d)
# 圆圈显⽰每个特征点
for i in range(68):
cv2.circle(im_rd,(shape.part(i).x, shape.part(i).y),2,(0,255,0),-1,8)
self.face_high =(shape.part(8).y - shape.part(19).y + shape.part(8).y - shape.part(
18).y + shape.part(8).y - shape.part(24).y)/3
# 分析任意n点的位置关系来作为表情识别的依据
mouth_width =(shape.part(54).x - shape.part(48).x)/ self.face_width #嘴巴咧开程度
mouth_higth =(shape.part(66).y - shape.part(62).y)/ self.face_high #嘴巴张开程度
sheet.write(m, n,str(mouth_width))
n = n +1
sheet.write(m, n, mouth_higth)
n = n +1
brow_sum =0# ⾼度之和
frown_sum =0# 两边眉⽑距离之和
for j in range(17,21):
brow_sum +=(shape.part(j).y - d.top())+(shape.part(j +5).y - d.top())
frown_sum += shape.part(j +5).x - shape.part(j).x
line_brow_x.append(shape.part(j).x)
line_brow_y.append(shape.part(j).y)
tempx = np.array(line_brow_x)
tempy = np.array(line_brow_y)
z1 = np.polyfit(tempx, tempy,1)# 拟合成⼀次直线
self.brow_k =-round(z1[0],3)
brow_hight =(brow_sum /10)/ self.face_width  # 眉⽑⾼度占⽐
brow_width =(frown_sum /5)/ self.face_high  # 眉⽑距离占⽐
#⼈脸特征值之眉⾼值的读⼊
sheet.write(m, n,round(brow_hight,3))
n = n +1
#⼈脸特征值之眉宽值的读⼊
sheet.write(m, n,round(brow_width,3))
n = n +1
# 眼睛睁开程度
eye_sum =(shape.part(41).y - shape.part(37).y + shape.part(40).y - shape.part(38).y )
shape.part(47).y - shape.part(43).y + shape.part(46).y - shape.part(44).y)
eye_hight =(eye_sum /4)/ self.face_high
#⼈脸特征之眼⾼值的读⼊
sheet.write(m, n,round(eye_hight,3))
n = n +1
#⼈脸特征值之眉⽑倾斜程度的读⼊
#sheet.write(m,n,self.brow_k)
#保存xls⼯作簿
book.save()
3.2.3 模型的设计(knn与svm)
Scikit-learn也简称 sklearn, 是机器学习领域当中最知名的 python 模块之⼀,期中包含了许多集成的机器学习模型,在此次的课程设计中,我们采取了knn和svm两种分类器,通过给分类器喂相应的训练数据与标签,得到.m模型⽂件。
⾸先根据采集到的特征值,打上相应的标签:1,2,5,6,7,分别代表:⽣⽓、伤⼼、开⼼、正常、惊讶五种表情。再根据sklearn库的官⽅⽂档,训练knn和svm分类器。
这⾥只贴出KNN分类器主要部分代码,SVM分类器的可以学习着写,不难。
#读取数据集xlsx⽂件,利⽤pandas库根据列来分特征值和标签列
file_loc =""
X = pd.read_excel(file_loc, index_col=None, na_values=['NA'], parse_cols ="A,B,C,D,E")
y = pd.read_excel(file_loc, index_col=None, na_values=['NA'], parse_cols ="G")
#给模型喂数据,调⽤sklearn中的集成好的分类器函数
model = sk_neighbors.KNeighborsClassifier(n_neighbors=5,n_jobs=1)
model.fit(X,y)
#评估模型,根据给定数据与标签返回正确率的均值
acc=model.score(X,y)
print('KNN模型(分类)评价:',acc)
#保存模型
joblib.dump(model,"")
根据最后的结果,可以发现,knn分类器的评估分值⽐svm的⾼,因此我们采⽤了knn分类器,在后来调⽤模型时候,我们分别采⽤了knn 和svm训练后的模型,在识别过程中,识别效果跟模型的评估分值成正⽐关系。因此最后确定的是knn模型。
3.2.4 模型的调⽤与识别
先判断眼睛睁开距离与识别框⾼度之⽐来确定是否状态为tired。若是,则播放提⽰⾳提醒驾驶员;若不是,则再通过调⽤已经完成的KNN 分类模型,进⼀步对摄像头捕捉到的⼈脸表情进⾏判定分类,若判定表情为愤怒(路怒状态),则播放提⽰⾳提⽰驾驶员注意⼼态。
具体实现代码:
import joblib
import cv2
import music
def face_pd(im_rd,a,b,c,d,dd,e):
#如果眼睛睁开距离与识别框⾼度之⽐⼩于0.2,则判定为闭眼,疲劳状态
if(e <0.02):
cv2.putText(im_rd,"tired",(d.left(), d.bottom()+20), cv2.FONT_HERSHEY_SIMPLEX,0.8,
(0,0,255),2,4)
#播放疲劳提⽰⾳
music.runtired()
else:
cld = joblib.load(".m")
x =[[a, b, c, dd, e]]
# 存储特征值
# a-嘴巴宽度与识别框宽度之⽐
# b-嘴巴⾼度与识别框⾼度之⽐
# c-眉⽑⾼度占⽐
# dd-眉⽑距离占⽐
# e-眼睛睁开程度
kll =int(cld.predict(x))#⽤训练好的KNN模型对获取的特征值进⾏分析分类,返回分类后的标签
#根据标签判断当前表情,并在图像上输出
if(kll ==1):
cv2.putText(im_rd,"angry",(d.left(), d.bottom()+20), cv2.FONT_HERSHEY_SIMPLEX,0.8,
(0,0,255),2,4)
#检测愤怒表情
music.runangry()
elif(kll ==2):
cv2.putText(im_rd,"sadness",(d.left(), d.bottom()+20), cv2.FONT_HERSHEY_SIMPLEX,0.8,
(0,0,255),2,4)
elif(kll ==5):
cv2.putText(im_rd,"happy",(d.left(), d.bottom()+20), cv2.FONT_HERSHEY_SIMPLEX,0.8,
(0,0,255),2,4)
elif(kll ==6):
cv2.putText(im_rd,"normal",(d.left(), d.bottom()+20), cv2.FONT_HERSHEY_SIMPLEX,0.8,
(0,0,255),2,4)
elif(kll ==7):
cv2.putText(im_rd,"surprise",(d.left(), d.bottom()+20), cv2.FONT_HERSHEY_SIMPLEX,0.8,
(0,0,255),2,4)
四.结果与分析
结果不给予太多的内容,代码可以去Git中拉去
4.1模型训练结果⽐较4.1.1 KNN模型
1. 五维特征
2. 六维特征
4.1.2 SVM模型
1. 五维特征民商法争鸣
2. 六维特征
4.2 表情识别效果

本文发布于:2024-09-25 02:21:26,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/326291.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:降维方法
下一篇:weka实验报告
标签:表情   特征   识别   分类   模型   学习   数据
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议