人脸检测及识别python实现系列(3)——为模型训练准备人脸数据

时间:2023-03-09 00:50:22
人脸检测及识别python实现系列(3)——为模型训练准备人脸数据

人脸检测及识别python实现系列(3)——为模型训练准备人脸数据

机器学习最本质的地方就是基于海量数据统计的学习,说白了,机器学习其实就是在模拟人类儿童的学习行为。举一个简单的例子,成年人并没有主动教孩子学习语言,但随着孩子慢慢长大,自然而然就学会了说话。那么孩子们是怎么学会的呢?很简单,在人类出生之前,有了听觉开始,就开始不断听到各种声音。人类的大脑会自动组织、分类这些不同的声音,形成自己的认识。随着时间的推移,大脑接收到的声音数据越来越多。最终,大脑利用一种我们目前尚未知晓的机制建立了一个成熟、可靠的声音分类模型,于是孩子们学会了说话。机器学习也是如此,要想识别出这张人脸属于谁,我们同样需要大量的本人和其他人的人脸数据,然后将这些数据输入Tensorflow这样的深度学习(深度学习指的是深度神经网络学习,乃机器学习分支之一)框架,利用深度学习框架建立属于我们自己的人脸分类模型。只要数据量足够,分类准确率就能提高到足以满足我们需求的级别。

日本程序员提供的源码利用了keras这个深度学习库来训练自己的人脸识别模型。keras是一个上层的神经网络学习库,纯python编写,被集成进了Tensorflow和Theano这样的深度学习框架。其存在的目的就是简化开发复杂度,能够让你迅速出产品,更关键的是,keras有中文文档;),有兴趣的请点这里:keras中文文档。由于我的机器已经安装了Tensorflow,因此我直接使用了keras的Tensorflow版。同时,为了验证其它深度学习库的效率和准确率,当然也为了满足我的好奇心,我还使用了Theano,利用CNN——卷积神经网络来训练我的人脸识别模型。我会在接下来的几节讲述这些内容,本节专注把训练数据准备好。

首先,我们需要大量自己的脸部图片,怎么获取呢?很简单,利用前两节讲到的知识就可以了,我们只是在前面代码的基础上增加脸部图像存储功能即可,先把完整代码贴出来:

 #-*- coding: utf-8 -*-

 import cv2
import sys from PIL import Image def CatchPICFromVideo(window_name, camera_idx, catch_pic_num, path_name):
cv2.namedWindow(window_name) #视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
cap = cv2.VideoCapture(camera_idx) #告诉OpenCV使用人脸识别分类器
classfier = cv2.CascadeClassifier("/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml") #识别出人脸后要画的边框的颜色,RGB格式
color = (0, 255, 0) num = 0
while cap.isOpened():
ok, frame = cap.read() #读取一帧数据
if not ok:
break grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #将当前桢图像转换成灰度图像 #人脸检测,1.2和2分别为图片缩放比例和需要检测的有效点数
faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.2, minNeighbors = 3, minSize = (32, 32))
if len(faceRects) > 0: #大于0则检测到人脸
for faceRect in faceRects: #单独框出每一张人脸
x, y, w, h = faceRect #将当前帧保存为图片
img_name = '%s/%d.jpg'%(path_name, num)
image = frame[y - 10: y + h + 10, x - 10: x + w + 10]
cv2.imwrite(img_name, image) num += 1
if num > (catch_pic_num): #如果超过指定最大保存数量退出循环
break #画出矩形框
cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), color, 2) #显示当前捕捉到了多少人脸图片了,这样站在那里被拍摄时心里有个数,不用两眼一抹黑傻等着
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame,'num:%d' % (num),(x + 30, y + 30), font, 1, (255,0,255),4) #超过指定最大保存数量结束程序
if num > (catch_pic_num): break #显示图像
cv2.imshow(window_name, frame)
c = cv2.waitKey(10)
if c & 0xFF == ord('q'):
break #释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows() if __name__ == '__main__':
if len(sys.argv) != 4:
print("Usage:%s camera_id face_num_max path_name\r\n" % (sys.argv[0]))
else:
CatchPICFromVideo("截取人脸", int(sys.argv[1]), int(sys.argv[2]), sys.argv[3])

依然很简单的代码,只是增加了不到10行代码,程序能够指定要截取的人脸数量,由cv2.imwrite()函数完成实际的保存,到达指定数量程序会自动退出。同时,在图像上提供了信息输出功能,以便我们能随时知道已经截取了多少张人脸,当然前提是你在一定距离之外还能看清楚屏幕。整个流程还是比较简单的,不多说了。我们需要利用这个程序准备至少1000张自己的人脸图片,将其单独放到一个文件夹下,如下图:

人脸检测及识别python实现系列(3)——为模型训练准备人脸数据

我将它们放到了与程序同路径的”data/me“文件夹下。然后我们还需要截取至少另外一个人的图片以便训练程序分类使用,以提高模型准确度。我截取的我闺女的,将其存储到了data/other文件夹下,同样也是1000张。注意一定要确保每个文件夹下的所有图片都是同一个人的(对于我来说data/me是我的,data/other全部是闺女的),接下来的训练程序将以文件夹作为标签数据区分个人。

前面已经说过,OpenCV对人脸的识别也不是100%准确,因此,我们截取的人脸图像中会有些不合格的,比如误把灯笼当人脸存下来了或者人脸图像很模糊。在我截取的1000张人脸中大约有几十张这样的,要想确保模型可靠,必须要把这样的图片去掉。这个活只能手动了,没办法。幸运的是,数据量不大,不会耽误太多时间的。最后,请确保程序所在路径下已经有了data/me和data/other两个文件夹及各1000张人脸图片。下一篇博文将讲述如何利用这些已经准备好的数据训练我们的识别模型。