python3+dlib实现人脸识别和情绪分析


Posted in Python onApril 21, 2018

一、介绍

我想做的是基于人脸识别的表情(情绪)分析。看到网上也是有很多的开源库提供使用,为开发提供了很大的方便。我选择目前用的比较多的dlib库进行人脸识别与特征标定。使用python也缩短了开发周期。

官网对于dlib的介绍是:Dlib包含广泛的机器学习算法。所有的设计都是高度模块化的,快速执行,并且通过一个干净而现代的C ++ API,使用起来非常简单。它用于各种应用,包括机器人技术,嵌入式设备,手机和大型高性能计算环境。

虽然应用都比较高大上,但是自己在PC上做个情绪分析的小软件还是挺有意思的。

按照自己的想法与思路设计识别方式。目前也比较火的keras好像就是根据嘴型的变化作为情绪分析的一个指标。

而我的想法是利用嘴的张开比例,眼睛的睁开程度,眉毛的倾斜角度作为情绪分析的三个指标。但是由于人与人长相的差异较大,五官的也是千差万别,再加上我的计算方法也比较简单。所以识别效率并不是很高。

识别规则:

1、嘴巴张开距离占面部识别框宽度的比例越大,说明情绪越激动,可能是非常开心,也可能是极度愤怒。

2、眉毛上扬,17-21 或者 22-26 号特征点距离面部识别框顶部与识别框高度的比值越小,说明眉毛上扬越厉害,可表示惊讶、开心。眉毛的倾斜角度,开心时眉毛一般是上扬,愤怒时皱眉,同时眉毛下压的比较厉害。

3、眯眼睛,人在开怀大笑的时候会不自觉的眯起眼睛,愤怒或者惊讶的时候会瞪大眼睛。

系统缺点:不能捕捉细微表情的变化,只能大致的判断出人的情绪,开心、愤怒、惊讶、自然。

系统优点:结构简单,易于上手。

应用领域:微笑抓拍,捕捉瞬间的美好、缓解儿童自闭症、交互式游戏开发。

由于人感情的复杂性,这些表情确实不能完完全全的代表一个人内心深处的情绪波动,如要提高判断的准确性,则需要心率检测、语音处理等综合评价。

二、开发环境搭建:

1、安装VS2015,因为最新版的dlib-19.10需要这个版本的vscode

2、安装opencv(whl方式安装):

从pythonlibs下载需要的版本whl文件,比如(opencv_python?3.3.0+contrib?cp36?cp36m?win_amd64.whl)
然后在本地使用pip install 安装。 注意文件位置下安装(如:C:\download\xxx.whl)

3、安装dlib(whl方式安装):

在这里下载dlib的各种版本的whl文件,然后在根目录下打开cmd直接安装即可。

但是为了学习使用dlib中的各种python实例程序,还是需要下载一个dlib的压缩包。

直接访问dlib官网即可下载:http://dlib.net/ml.html

dlib各种版本的whl文件:https://pypi.python.org/simple/dlib/

4、如果想要使用人脸模型特征标定的话,还需要一个人脸面部形状预测器,这个可以通过自己的照片进行训练,也可以使用dlib作者给出的一个训练好的预测器:         

点击下载:http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2

三、实施思路

python3+dlib实现人脸识别和情绪分析

四、具体步骤

首先是利用dlib进行人脸识别:)

import cv2
import dlib
from skimage import io

# 使用特征提取器get_frontal_face_detector
detector = dlib.get_frontal_face_detector()
# dlib的68点模型,使用作者训练好的特征预测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# 图片所在路径
img = io.imread("2.jpg")
# 生成dlib的图像窗口
win = dlib.image_window()
win.clear_overlay()
win.set_image(img)

# 特征提取器的实例化
dets = detector(img, 1)
print("人脸数:", len(dets))

for k, d in enumerate(dets):
    print("第", k+1, "个人脸d的坐标:",
       "left:", d.left(),
       "right:", d.right(),
       "top:", d.top(),
       "bottom:", d.bottom())

    width = d.right() - d.left()
    heigth = d.bottom() - d.top()

    print('人脸面积为:',(width*heigth))

然后实例化一个 shape_predictor 对象,使用dlib作者训练好人脸特征检测器,进行人脸的特征点标定。

标定的时候使用opencv的circle方法,在特征点的坐标上面添加水印,内容就是特征点的序号和位置。

# 利用预测器预测
    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))
    # 显示一下处理的图片,然后销毁窗口
    cv2.imshow('face', img)
    cv2.waitKey(0)

到此,68个特征点的信息就获取到了,下面就需要跟根据这个68个特征点的坐标信息,进行综合 计算,作为每个表情的判断指标。

python3+dlib实现人脸识别和情绪分析

根据上面说到的我的判断指标,先计算嘴巴的张开比例,由于人离摄像头距离的远近,导致人脸识别框的大小不一,故选择比例来作为判断指标。

在选择指标的标准数值之前,先对多个开心的人脸照片进行分析。计算开心时的嘴巴张卡比例的平均。

下面是截取对人眉毛的数据处理方法,对左边眉毛上面的5个特征点进行线性拟合,拟合出一个一次函数直线,用拟合直线的斜率近似代表眉毛的倾斜程度。

# 眉毛
          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)

          self.excel_brow_hight.append(round((brow_sum/10)/self.face_width,3))
          self.excel_brow_width.append(round((frown_sum/5)/self.face_width,3))
          brow_hight[0]+= (brow_sum/10)/self.face_width    # 眉毛高度占比
          brow_width[0]+= (frown_sum/5)/self.face_width    # 眉毛距离占比

          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)  # 拟合出曲线的斜率和实际眉毛的倾斜方向是相反的

我计算了25个人脸的开心表情的嘴巴张开比例、嘴巴宽度、眼睛张开程度、眉毛倾斜程度,导入excel表格生成折线图:

python3+dlib实现人脸识别和情绪分析

通过折线图能很明显的看出什么参数可以使用,什么参数的可信度不高,什么参数在那个范围内可以作为一个指标。

同样的方法,计算人愤怒、惊讶、自然时的数据折线图。

通过对多个不同表情数据的分析,得出每个指标的参考值,可以写出简单的表情分类标准:

# 分情况讨论
            # 张嘴,可能是开心或者惊讶
            if round(mouth_higth >= 0.03):
              if eye_hight >= 0.056:
                cv2.putText(im_rd, "amazing", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8,
                      (0, 0, 255), 2, 4)
              else:
                cv2.putText(im_rd, "happy", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8,
                      (0, 0, 255), 2, 4)

            # 没有张嘴,可能是正常和生气
            else:
              if self.brow_k <= -0.3:
                cv2.putText(im_rd, "angry", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8,
                      (0, 0, 255), 2, 4)
              else:
                cv2.putText(im_rd, "nature", (d.left(), d.bottom() + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.8,
                      (0, 0, 255), 2, 4)

五、实际运行效果:

python3+dlib实现人脸识别和情绪分析

识别之后:

python3+dlib实现人脸识别和情绪分析

 

完整项目代码:https://gitee.com/Andrew_Qian/face/blob/master/from_video.py

大家如果在测试制作的时候有任何疑问可以在下方的留言区讨论,感谢大家对三水点靠木的支持。

Python 相关文章推荐
Python中字典(dict)和列表(list)的排序方法实例
Jun 16 Python
Python中利用sorted()函数排序的简单教程
Apr 27 Python
Python实现简单的代理服务器
Jul 25 Python
从头学Python之编写可执行的.py文件
Nov 28 Python
python分批定量读取文件内容,输出到不同文件中的方法
Dec 08 Python
python爬虫爬取微博评论案例详解
Mar 27 Python
selenium 安装与chromedriver安装的方法步骤
Jun 12 Python
Python3远程监控程序的实现方法
Jul 15 Python
Django后端接收嵌套Json数据及解析详解
Jul 17 Python
详解在Python中以绝对路径或者相对路径导入文件的方法
Aug 30 Python
Python猜数字算法题详解
Mar 01 Python
Python3+PyCharm+Django+Django REST framework配置与简单开发教程
Feb 16 Python
Python通过属性手段实现只允许调用一次的示例讲解
Apr 21 #Python
使用Python和xlwt向Excel文件中写入中文的实例
Apr 21 #Python
使用pandas读取csv文件的指定列方法
Apr 21 #Python
Python 3.7新功能之dataclass装饰器详解
Apr 21 #Python
pandas or sql计算前后两行数据间的增值方法
Apr 20 #Python
对pandas进行数据预处理的实例讲解
Apr 20 #Python
pandas 两列时间相减换算为秒的方法
Apr 20 #Python
You might like
php实例分享之通过递归实现删除目录下的所有文件详解
2014/05/15 PHP
PHP常用正则表达式集锦
2014/08/17 PHP
PHP开发Apache服务器配置
2015/07/15 PHP
PHP内核学习教程之php opcode内核实现
2016/01/27 PHP
利用Laravel事件系统如何实现登录日志的记录详解
2017/05/20 PHP
jquery 表单取值常用代码
2009/12/22 Javascript
JavaScript DOM 学习第五章 表单简介
2010/02/19 Javascript
jQuery实现的一个自定义Placeholder属性插件
2014/08/11 Javascript
JavaScript判断手机号运营商是移动、联通、电信还是其他(代码简单)
2015/09/25 Javascript
JavaScript学习小结(7)之JS RegExp
2015/11/29 Javascript
理解js对象继承的N种模式
2016/01/25 Javascript
gulp-htmlmin压缩html的gulp插件实例代码
2016/06/06 Javascript
JavaScript中boolean类型之三种情景实例代码
2016/11/21 Javascript
bootstrap table使用入门基本用法
2017/05/24 Javascript
详谈js对url进行编码和解码(三种方式的区别)
2017/08/16 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
JavaScript中set与get方法用法示例
2018/08/15 Javascript
vue-cli设置publicPath小记
2020/04/14 Javascript
js实现九宫格布局效果
2020/05/28 Javascript
pygame实现弹力球及其变速效果
2017/07/03 Python
在python里从协程返回一个值的示例
2019/02/19 Python
基于Django实现日志记录报错信息
2019/12/17 Python
jupyternotebook 撤销删除的操作方式
2020/04/17 Python
python 中的命名空间,你真的了解吗?
2020/08/19 Python
Eyeko美国:屡获殊荣的睫毛膏、眼线笔和眉妆
2018/07/05 全球购物
Eagle Eyes Optics鹰眼光学:高性能太阳镜
2018/12/07 全球购物
英国领先的独立酒精饮料零售商:DrinkSupermarket
2021/01/13 全球购物
锐步香港官方网上商店:Reebok香港
2020/11/05 全球购物
大学军训感言
2014/01/10 职场文书
电大毕业自我鉴定
2014/02/03 职场文书
幼儿园园长新年寄语2015
2014/12/08 职场文书
毕业论文指导教师评语
2014/12/30 职场文书
餐饮食品安全责任书
2015/01/29 职场文书
2015年教师节感恩寄语
2015/03/23 职场文书
交通事故被告答辩状
2015/05/22 职场文书
python实战之用emoji表情生成文字
2021/05/08 Python