• 技术文章 >后端开发 >Python教程

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

    不言不言2018-05-30 14:10:28原创6243
    本文通过具体代码不步骤给大家详细讲述了python3+dlib实现人脸识别以及情绪分析的方法,有需要的朋友参考下。

    一、介绍

    我想做的是基于人脸识别的表情(情绪)分析。看到网上也是有很多的开源库提供使用,为开发提供了很大的方便。我选择目前用的比较多的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

    三、实施思路

    四、具体步骤

    首先是利用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个特征点的坐标信息,进行综合 计算,作为每个表情的判断指标。

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

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

    下面是截取对人眉毛的数据处理方法,对左边眉毛上面的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表格生成折线图:

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

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

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

    # 分情况讨论
                # 张嘴,可能是开心或者惊讶
                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实现人脸识别和情绪分析的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:python3+dlib 情绪 识别
    上一篇:Python中的@classmethod 下一篇:Python通过属性手段实现只允许调用一次的示例讲解_python

    相关文章推荐

    • 使用Python的Zato发送AMQP消息的教程• 在服务器端实现无间断部署Python应用的教程• 初步探究Python程序的执行原理• 在Python的Flask框架下使用sqlalchemy库的简单教程• 用Python实现一个简单的能够发送带附件的邮件程序的教程

    全部评论我要评论

  • 闫冬

    情绪表情张开比例怎么算,用什么算法,公式

    2019-12-03

  • Winter

    参数指标是根据什么文献参考的吗?

    2020-05-27

  • 吕大娟坐直了吗

    想问下可以分享下代码吗

    2020-11-08

  • 取消发布评论发送
  • 1/1

    PHP中文网