资源下载地址:https://download.csdn.net/download/sheziqiong/85660758
面部表情识别
练习技能:
- 爬虫
- 数据清洗
- 计算机视觉(图片基本处理,信息提取)
- 深度学习
图像识别技术文档
一、项目概述
-
项目名称:面部表情识别
-
项目背景:在与客户交流的过程中,通过客户的面部表情来判断用户对话题是否感兴趣,营销人员或者沟通人员可以从中找到客户感兴趣的方面,或者判断客户的购买欲望
-
图像识别是指利用计算机对图像进行处理、分析、理解,图像识别的过程可分为图像处理和图像分析两个过程
图像处理是指对所需要分析的图像进行一系列的图形操作,包括拉伸缩放、旋转翻转、颜色变换、像素保留……,图像分析是指通过图像的特征来反馈图像信息并且分类,最简单的是基于统计的方法、最常用的是深度学习方法 -
技术支持
图像处理:VoTT、OpenCV、PIL
图像分析:TensorFlow、Keras、CNN
二、应用领域
总体目标
- 一级目标
- 通过客户的面部表情变化,来抓住客户感兴趣的点,提高沟通效率
- 二级目标
- 学习图像识别的技术
- 三级目标
- 学习深度学习实现工具
- 四级目标
- 了解图像识别技术实现的步骤,技术原理
三、实验步骤
3.1 资源
- 数据资源:本次实验为面部表情的二分类识别,情绪为高兴和沮丧,各表情图像 5000 张
- 技术支持:Keras、TensorFlow、VoTT、OpenCV、PIL
Keras
Keras 是一个由 Python 编写的开源人工神经网络库,可以作为 Tensorflow、Microsoft-CNTK 和 Theano 的高阶应用程序接口,进行深度学习模型的设计、调试、评估、应用和可视化,Keras 的神经网络 API 是在封装后与使用者直接进行交互的 API 组件,在使用时可以调用 Keras 的其它组件。除数据预处理外,使用者可以通过神经网络 API 实现机器学习任务中的常见操作,包括人工神经网络的构建、编译、学习、评估、测试等。
TensorFlow
TensorFlow 由谷歌人工智能团队谷歌大脑(Google Brain)开发和维护,拥有包括 TensorFlow Hub、TensorFlow Lite、TensorFlow Research Cloud 在内的多个项目以及各类[应用程序接口]( API) [2] 。自 2015 年 11 月 9 日起,TensorFlow 依据阿帕奇授权协议(Apache 2.0 open source license)开放源代码,TensorFlow 是一个基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machine learning)算法的编程实现,谷歌大脑自 2011 年成立起开展了面向科学研究和谷歌产品开发的大规模深度学习应用研究,其早期工作即是 TensorFlow 的前身 DistBelief。
VoTT
VoTT 是一个用 TypeScript 编写的 React + Redux Web 应用程序。该项目是通过 Create React App 启动的,用于图像和视频资产的开源注释和标签工具,VoTT 可以作为本机应用程序安装,也可以从源代码运行。VoTT 也可以作为独立的 Web 应用程序使用,并且可以在任何现代 Web 浏览器中使用。
OpenCV
OpenCV 是一个基于 BSD 许可(开源)发行的跨平台计算机视觉库,可以运行在 Linux、Windows、Android 和 Mac OS 操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了 Python、Ruby、MATLAB 等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
PIL
python 图像处理库,这个库支持多种文件格式,并提供了强大的图像处理和图形处理能力。
3.2 方法
3.2.1 试验阶段
- 在项目开始初步试验阶段,通过人工百度搜索人像表情图像,利用 VoTT 工具进行裁切和标注,各表情 100 张,并按照 7,2,1 的比列把数据分为训练集、测试集、验证集。
- 利用 Keras 深度学历框架搭建简单的 CNN 进行训练,结果显示 CNN 在图像处理领域效果很不错,在模型未经过调整前准确率能超过 50%。
3.2.2 中期工作
-
扩大数据集,利用爬虫批量获取人像图片,在爬取百度图片的过程中,如果直接获取那最多只能获取到 30 张图像,之后程序就自动停止了,采用的解决方法是,通过观察 url 发现可以添加 page 页码这个选择来达到滚轮向下刷新图片的作用,因此添加一个页码循环来爬取图像。
所以采用 VoTT 加 Python 的方式来完成图像标注和裁切,在 VoTT 新建项目,选择图像位置进行框选和标注,完成后保存导出 JSON 格式文件,在利用 Python 读取 JSON 文件,打开对应图像按照框选的大小进行裁切,然后转化为数组也就是像素保存,按照 6,2,2 的比例划分数据集保存 CSV 文件。
-
打开 VoTT,选择新建项目
-
新建连接点
-
选择为添加位置
-
选择图像所在文件夹位置,添加确认
-
工作界面右上角区域为标签处理区域,可以进行标签的添加删除和位置更改操作
-
正上方区域为框选工作区域
-
左边为文件选项,可以选择框选图像已经导出
-
标注好的图像导出为 JSON 格式
-
卷积神经网络和普通神经网络的区别主要在于“卷积”二字,卷积也就是我们说的内积计算方式,就是将矩阵相乘再相加,卷积的操作是为了提取区域的主要特征,也是一种减少维度的方法,并且在图像识别中这种方式也是很合理的,卷积这个操作最开始来自于计算机波纹处理,后来应用到计算机视觉领域得到了显著的作用。
-
卷积操作可以作为物体的边缘检测,这在图像识别上提供了很大的帮助,在将我们的滤波器放在选中的像素上之后,我们将卷积核中的每一个数值和图像中对应的数值成对相乘。最后将乘积的结果相加,然后把结果放在输出特征图的正确位置上。我们在上边的动画中可以以一个微观的形式看到这个运算的过程,但是更有趣的是我们在整幅图像上执行这个运算得到的结果。
-
“池化”操作是和“卷积”配合使用,池化操作也是一种提取重要特征的方式,但是在这一环节中没有权重产生,它的工作方式是指定池化的大小,对数据进行扫描保留区域内最大数值,这个操作也可以保留区域内的平均数值。除了卷积层,CNN 通常会用到所谓的池化层。它们最早被用来减小张量的大小以及加速运算。这些层是比较简单的——我们需要将我们的图像分成不同的区域,然后在每一个部分上执行一些运算。例如,对 Max Pool 层而言,我们会选择每个区域的最大值,并将它放到对应的输出区域。与卷积层的情况一样,我们有两个可用的超参数——滤波器大小和步长。最后但同样重要的一点是,如果你对一个多通道的图像执行池化操作,那么每一个通道的池化应该单独完成。
-
“全连接”,此操作是将图像数组进行平压之后全连接,之后的操作和普通的神经网络原理一致,最后的输出层利用逻辑函数进行预测。
-
数据输入,在数据输入过程中添加 Keras 图像生成器模块,扩大数据集。
-
效果展示
3.2.5 模型评估
-
训练集
0 1 0 4749 216 1 283 6933 评估 百分比 真阳率 96.98% 假阳率 3.02% 真阴率 5.62% 假阴率 94.38% 召回率 96.08% -
测试集
0 1 0 562 64 1 76 803 评估 百分比 真阳率 92.62% 假阳率 7.38% 真阴率 11.91% 假阴率 88.09% 召回率 91.35%
-
实时预测
对面部表情进行实时识别需要计算机获取摄像头的信息,思路是通过获取计算机摄像头的权限,打开摄像头进行实时画面的捕捉,获取当前画面的一帧来做预测,根据刷新率不同识别的实时速率也不同
#-*- coding: utf-8 -*-import cv2 import sys import gc import json import numpy as np from keras.models import Sequential from keras.models import model_from_json root_path=os.path.abspath(".") model_path=root_path+'/model/' img_size=48 emo_labels = ["happy", 'disgust'] num_class = len(emo_labels) json_file=open(model_path+'model_json.json') loaded_model_json = json_file.read() json_file.close() model = model_from_json(loaded_model_json) model.load_weights(model_path+'model_weight.h5')if __name__ == '__main__':if len(sys.argv) == 1:print(len(sys.argv))print("Usage:%s camera_id\r\n" % (sys.argv[0]))sys.exit(0)#框住人脸的矩形边框颜色color = (0, 0, 2555)#捕获指定摄像头的实时视频流cap = cv2.VideoCapture(0)#人脸识别分类器本地存储路径cascade_path ="C:/ProgramData/Anaconda3/lib/site-packages/cv2/data/haarcascade_frontalface_alt.xml"#循环检测识别人脸while True:_, frame = cap.read() #读取一帧视频#图像灰化,降低计算复杂度frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#使用人脸识别分类器,读入分类器cascade = cv2.CascadeClassifier(cascade_path)#利用分类器识别出哪个区域为人脸faceRects = cascade.detectMultiScale(frame_gray, scaleFactor = 1.1,minNeighbors = 1, minSize = (120, 120))if len(faceRects) > 0:for faceRect in faceRects:x, y, w, h = faceRectimages=[]rs_sum=np.array([0.0]*num_class)image = frame_gray[y: y + h, x: x + w ]image=cv2.resize(image,(img_size,img_size))image=image*(1./255)images.append(image)images.append(cv2.flip(image,1))images.append(cv2.resize(image[2:45,:],(img_size,img_size)))for img in images:image=img.reshape(1,img_size,img_size,1)list_of_list = model.predict_proba(image,batch_size=32,verbose=1)result = [prob for lst in list_of_list for prob in lst]rs_sum+=np.array(result)print(rs_sum)label=np.argmax(rs_sum)emo = emo_labels[label]print ('Emotion : ',emo)cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, thickness = 2)font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(frame,'%s' % emo,(x + 30, y + 30), font, 1, (255,0,255),4)cv2.imshow("识别朕的表情!", frame)#等待10毫秒看是否有按键输入k = cv2.waitKey(30)#如果输入q则退出循环if k & 0xFF == ord('q'):break#释放摄像头并销毁所有窗口cap.release()cv2.destroyAllWindows()
资源下载地址:https://download.csdn.net/download/sheziqiong/85660758