基于卷积神经网络的人脸识别的实现
利用opencv获取人脸,采集人脸数据,将收集到的人脸数据加载到内存,搭建属于自己的卷积神经网络,并用人脸数据训练自己的网络,将训练好的网络保存成模型,最后再用opencv获取实时人脸用先前训练好的模型来识别人脸。
1.前言
随着社会的不断进步以及各方面对于快速有效的自动身份验证的迫切要求,生物特征识别技术在近几十年得到了飞速的发展。作为人的一种内在属性,并且具有很强的自身稳定性及个体差异性,生物特征成为了自动身份验证的最理想依据。当前的生物特征识别技术主要包括有:指纹识别,视网膜识别,虹膜识别,步态识别,静脉识别,人脸识别等。与其他识别方法相比,人脸识别由于具有直接,友好,方便的特点,使用者无任何心理障碍,易于为用户所接受,从而得到了广泛的研究与应用。
2.系统设计
2.1 系统开发环境
硬件:
CUP: INTEL CORE I7-6500U
GPU: NVIDIA GeForce 940M
内存:8G
硬盘:PCIE SSD 256G
软件:
Python 3.5
2.2 系统使用工具
集成开发环境:
IDLE(是安装好python之后,自动安装好的一个python自带的集成开发环境)
插件:
opencv3.4.3、numpy1.14.6、keras2.2.4、tensorflow cpu1.11.0和sklearn0.20.0。
这些插件的具体安装步骤,网上都可以找到具体的教程,这里便不再赘述。
2.3 系统功能需求
通过电脑本地的摄像头,拍摄实时人脸照片,与训练好的卷积神经网络模型中存放的人脸信息进行比对,同时在桌面上显示识别出的人脸标签值。
3.关键步骤
3.1 人脸数据的获取
利用opencv来调用摄像头,获取实时视频流,通过opencv自带的人脸分类器haar来识别并标注出人脸区域,将当前帧保存为图片存到指定的文件夹下面。
代码如下:
#catchpicture.py
import cv2
cap = cv2.VideoCapture(0)
num = 0
while cap.isOpened():
ret, frame = cap.read() #读取一帧数据
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)#将图片转化成灰度
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
face_cascade.load('F:\python35\haarcascade_frontalface_alt2.xml')#一定要告诉编译器文件所在的具体位置
'''此文件是opencv的haar人脸特征分类器'''
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
if len(faces) > 0:
for (x,y,w,h) in faces:
#将当前帧保存为图片
img_name = '%s/%d.jpg'%("F:\data\me", num)
image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
cv2.imwrite(img_name, image)
num += 1
if num > 1000: #如果超过指定最大保存数量退出循环
break
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
#显示当前捕捉到了多少人脸图片
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame,'num:%d'%(num),(x + 30,y + 30),font,1,(255,0,255),4)
#超过指定最大保存数量结束程序
if num > 1000 :break
#显示图像并等待10毫秒按键输入,输入‘q’退出程序
cv2.imshow("capture", frame)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
#释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows()
3.2 图片预处理
第一步获取到的人脸图片集中的每一张图片大小都不一样,为了后续操作的方便需要将,捕获到的人脸照片压缩为像素值为6464的并灰度化处理。所以图片预处理一共分为两部先是压缩成比例6464的,第一一步定义了一个resize_image()函数作用是先将图片补成正方形之后压缩成像素值为64*64,第二步利用opencv自带的cvtColor()函数将图片灰度化。
代码如下:
#picturepraction.py
import os
import cv2
IMAGE_SIZE = 64
def resize_image(image, height=IMAGE_SIZE, width=IMAGE_SIZE):
top, bottom, left, right = (0, 0, 0, 0)
h, w, _ = image.shape
longest_edge = max(h, w)
if h < longest_edge:
dh = longest_edge - h
top = dh // 2
bottom = dh - top
elif w < longest_edge:
dw = longest_edge - w
left = dw // 2
righ = dw - left
else:
pass
BLACK = [0, 0, 0]
constant = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=BLACK)
return cv2.resize(constant, (height, width))
if __name__ == '__main__':
path_name = "F:\data\me"
i = 0
for dir_item in os.listdir(path_name):
full_path = os.path.abspath(os.path.join(path_name, dir_item