让“它”认出你
——使用快速入门人脸检测和人脸识别
,顾名思义“开源,计算机视觉”。 就是这么一个特殊的框架,一群大牛花时间打造了一个开源的计算机视觉框架。 有了它我们可以快速创建计算机视觉应用程序。 而这里我们将使用更快的——即接口。 如果你已经安装了 pip,只需执行“pip -”。 如果你没有安装,也很简单,下载安装即可,它自带了近乎完整的科学计算环境。 然后继续点。
借助上述工具,我们只需要使用几十行代码就可以快速实现人脸检测和人脸识别。 让“它”认识你。
人脸检测
人脸检测技术可以视为计算机视觉的基础技术之一。 即使在深度学习之前的时代,该技术也已经发展到了很高的程度。 在深度学习时代,人脸识别一般采用卷积神经网络进行监督学习,即通过让算法(神经网络)自己发现规则,创建一个有用的卷积核(一个矩阵),然后使用它查找图片和视频中的面孔。 在此之前,人们需要的是设计自己的算法来寻找人脸。 但后来人们发明了一种类似于深度学习思想的人脸找算法,那就是haar算法。
简单来说,这个算法就是通过计算一个区域内不同像素之间的灰度差来判断是否是人脸。 原理是有规律的图像,比如一个物体,无论光线明亮与否,不同区域之间的像素差异总是有一定的规律。 正是凭借这种特殊的想法,科学家们首次创建了极其有效的人脸识别算法。 而且它的计算性能要求确实很低。 即使在计算性能较低的 Pi 1,2硬件设备上也能快速运行。
内部集成了人脸检测算法,提供了训练好的人脸检测haar模型,保存在yml中。 我们只需要简单的调用类库即可对照片或视频进行人脸检测。 接下来,我们可以使用摄像头调用和图像处理模块以及人脸检测模块共同创建一个程序,可以实时检测来自摄像头的人脸数据,并剪切并保存相关数据。 有了它,我们可以创建一个标记人脸的数据库,然后可以将其用于人脸识别。
代码
第一步:加载haar数据,训练好的数据可以下载,或者从我的下载:
face_cascade =cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_cascade.load('./haarcascades/haarcascade_frontalface_default.xml')
步骤2:我们需要调用相机并读取相关数据。 同时,因为我们需要实时显示,所以我们创建一个循环,在循环中不断调用来获取相机中的图片并进行后续处理。
# 获取摄像头
camera = cv2.VideoCapture(0)
# 计数器,用于之后文件的保存
count = 0
# 创建 循环
while (True):
# 调用摄像头,获取图像
ret, frame = camera.read()
# 判断图像是否真实存在
if ret == True:
...
else:
print("no ret")
# 使用OpenCV获取键盘输入,如果输入q则退出窗口
if cv2.waitKey(int(1000 / 12)) & 0xFF == ord('q'):
break
步骤3:我们需要创建一个灰度图像,然后使用人脸检测器对处理后的图像进行人脸检测。 同时,我们利用人脸检测器返回的数据在原图中画出一个框并实时显示。
# 转换为灰度图
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 调用人脸检测器检测
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
# 绘制检测出的所有人脸
for (x, y, w, h) in faces:
# 画方框
img = cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
# 获取人脸,并转换为200,200的统一格式
# 原始数据返回的是正方形
f = cv2.resize(gray[y:y + h, x:x + w], (200, 200))
# 保存图片
cv2.imwrite('./data/at/tfs/%s.pgm' % str(count), f)
count += 1
# 展示图片
cv2.imshow('camera', frame)
经过这样的操作,我们就得到了一个人脸数据库,我们通过文件夹的名称来识别图片。
人脸识别
完成人脸检测后,我们就得到了一个可以用于人脸识别的人脸数据库。 之后我们就可以在人脸识别方法中调用人脸识别方法了,但是人脸识别方法的实现方法有很多种。 如果你现在想学习深度学习,免不了要长篇大论。 因此,这里我们将使用三种非深度学习方法进行人脸识别,详细介绍它们的用途,并简单介绍一下它们的原理。
代码
人脸识别在face类库中,自带了三个人脸识别器。 我们可以直接调用相关的类库进行训练和测试使用。 在此之前,我们首先创建一个链表,以矩阵的形式加载原来保存的图片。
import numpy as np
# 创建空链表
images = []
# 使用OpenCV加载fonttian的几张人脸照片
images.append(cv2.imread("data/at/fonttian/15.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/fonttian/17.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/fonttian/55.pgm",cv2.IMREAD_GRAYSCALE))
# 使用OpenCV加载zjz的几章人脸照片
images.append(cv2.imread("data/at/zjz/15.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/zjz/17.pgm",cv2.IMREAD_GRAYSCALE))
images.append(cv2.imread("data/at/zjz/60.pgm",cv2.IMREAD_GRAYSCALE))
# 创建标签
labels = [0,0,0,1,1,1]
之后我们就可以调用不同的人脸识别器进行人脸识别了。 配备三款人脸识别设备——LBPH、、。 我们首先创建一个方法来显示不同人脸识别器的判断结果和输出置信度。 置信范围将在下一步中详细描述。
# 创建测试文件路径
imgPath = "data/at/fonttian/570.pgm"
# 传入测试图片路径,识别器,原始人脸数据库,人脸数据库标签
def showConfidence(imgPath,recognizer,images,labels):
# 训练识别器
recognizer.train(images,np.array(labels))
# 加载测试图片
predict_image=cv2.imread(imgPath,cv2.IMREAD_GRAYSCALE)
# 预测并打印结果
labels,confidence = recognizer.predict(predict_image)
print("label=",labels)
print("conficence=",confidence)
以上步骤是人脸识别器的一般步骤。 本质上,人脸识别器与一般的机器学习模型相同。 分类需要标记数据。 因此首先需要使用标记数据进行训练,并使用新数据进行预测。 人脸识别器的关键是如何从人脸中提取特征并利用这些特征进行人脸识别。 这是人脸识别的永恒套路,以前如此,现在也如此。
它是一个基于PCA的人脸识别器。 一般置信度低于5000就判定为可靠。PCA是主成分分析。 它在人脸识别中的作用是提取人脸的主要信息来判断不同的人。
LBPH是局部二值模式直方图,局部二值指的是某一点像素与周围点的大小差异,0和1指的是大小关系。 其核心原理与haar类似,计算局部像素之间的差异关系进行图像识别。
它是一种基于线性判别式的人脸识别器。 线性判别在机器学习的很多领域都有广泛的应用,分类、聚类、推荐都存储在它里面。 这里的基本思想与PCA一致,都是通过降维得到人脸的人脸特征,然后通过人脸特征进行人脸识别。
具体置信度如下。 如果我们选择直接打印,程序会直接给出最好的结果,这可能足以用于测试。 但使用置信度来检测是更好的方法。
# EigenFace(PCA,5000以下判断可靠)
recognizer = cv2.face.EigenFaceRecognizer_create()
showConfidence(imgPath,recognizer,images,labels)
# LBPH(局部二值模式直方图,0完全匹配,50以下可接受,80不可靠)
recognizer = cv2.face.LBPHFaceRecognizer_create()
showConfidence(imgPath,recognizer,images,labels)
# Fisher(线判别分析 , 5000以下判断为可靠)
recognizer = cv2.face.FisherFaceRecognizer_create()
showConfidence(imgPath,recognizer,images,labels)
现在运行上面的代码就会告诉我们最终的结果。以下是运行结果
虽然人脸识别和人脸检测技术一直在发展,但准确率和计算量都在不断提高。 但作为一个应用程序或一个领域,一切都保持不变。 我们可以从几十行代码开始,逐步掌握深度学习下的人脸识别。