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 相关文章推荐
Python3基础之基本运算符概述
Aug 13 Python
Python中捕捉详细异常信息的代码示例
Sep 18 Python
Python连接MySQL并使用fetchall()方法过滤特殊字符
Mar 13 Python
浅谈Series和DataFrame中的sort_index方法
Jun 07 Python
对pandas中Series的map函数详解
Jul 25 Python
Python使用os.listdir()和os.walk()获取文件路径与文件下所有目录的方法
Apr 01 Python
PyQt5 窗口切换与自定义对话框的实例
Jun 20 Python
PyQt5实现画布小程序
May 30 Python
详解Python 函数参数的拆解
Sep 02 Python
Django利用elasticsearch(搜索引擎)实现搜索功能
Nov 26 Python
python爬虫之利用selenium模块自动登录CSDN
Apr 22 Python
Python实现抖音热搜定时爬取功能
Mar 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
天津市收音机工业发展史
2021/03/04 无线电
php通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
PHP预定义接口――Iterator用法示例
2020/06/05 PHP
捕获键盘事件(且兼容各浏览器)
2013/07/03 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
jquery自定义函数的多种方法
2014/01/09 Javascript
JavaScript中的prototype和constructor简明总结
2014/04/05 Javascript
深入分析Javascript事件代理
2016/01/30 Javascript
原生js实现水平方向无缝滚动
2017/01/10 Javascript
Vue.js基础学习之class与样式绑定
2017/03/20 Javascript
详解webpack+vue-cli项目打包技巧
2017/06/17 Javascript
微信小程序实现顶部普通选项卡效果(非swiper)
2020/06/19 Javascript
bootstrap table sum总数量统计实现方法
2017/10/29 Javascript
Vue批量图片显示时遇到的路径被解析问题
2019/03/28 Javascript
微信小程序保存图片到相册权限设置
2020/04/09 Javascript
原生JS实现天气预报
2020/06/16 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
2020/09/04 Javascript
python中二维阵列的变换实例
2014/10/09 Python
Python简单检测文本类型的2种方法【基于文件头及cchardet库】
2016/09/18 Python
PYTHON 中使用 GLOBAL引发的一系列问题
2016/10/12 Python
在cmd中运行.py文件: python的操作步骤
2018/05/12 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
2019/01/05 Python
用Python将结果保存为xlsx的方法
2019/01/28 Python
浅谈python输出列表元素的所有排列形式
2020/02/26 Python
Python读入mnist二进制图像文件并显示实例
2020/04/24 Python
使用pycharm和pylint检查python代码规范操作
2020/06/09 Python
优秀老员工获奖感言
2014/02/15 职场文书
实验室标语
2014/06/21 职场文书
终止劳动合同协议书
2014/10/05 职场文书
党员自我剖析材料(群众路线)
2014/10/06 职场文书
2014年第四季度入党积极分子思想汇报(十八届四中全会)
2014/11/03 职场文书
贷款担保书
2015/01/20 职场文书
沈阳故宫导游词
2015/01/31 职场文书
暑期社会实践新闻稿
2015/07/17 职场文书
vue router 动态路由清除方式
2022/05/25 Vue.js