干货 | 用python3+dlib教你的程序察言观色


访问flyai.club,一键建立你的人工智能项目html

做者 | Andrew_qianpython

www.cnblogs.com/qsyll0916/p/8893790.htmlgit

1、介绍算法

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

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

虽然应用都比较高大上,可是本身在PC上作个情绪分析的小软件仍是挺有意思的。ide

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

而个人想法是利用嘴的张开比例,眼睛的睁开程度,眉毛的倾斜角度做为情绪分析的三个指标。可是因为人与人长相的差别较大,五官的也是千差万别,再加上个人计算方法也比较简单。因此识别效率并非很高。函数

识别规则性能

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

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

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

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

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

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

因为人感情的复杂性,这些表情确实不能完彻底全的表明一我的心里深处的情绪波动,如要提升判断的准确性,则须要心率检测、语音处理等综合评价。

2、开发环境搭建

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

3、实施思路

4、具体步骤

首先是利用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)

5、实际运行效果:

识别以后:

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

— End —

相关文章
相关标签/搜索