让“它”认得你
——利用opencv快速入门人脸检测与人脸识别
opencv,顾名思义“开源,计算机视觉”。OpenCV就是这样的一个特殊的框架,一群大牛然绕自己的时间,制作了一个开源的计算机视觉框架。借助它我们可以快速的创建计算机视觉的应用。而我们这里将会使用更更加快速的OpenCV-Python,也就是OpenCV的Python接口。假如你已经安装了Python和pip,那么只需简单的执行“pip install opencv-python”即可。如果你没有安装Python,那么也很简单,下载Anaconda3,然后安装,其就自带近乎完整的Python科学计算环境。之后继续pip即可。
有了以上工具的帮助,我们只需要简单地使用几十行代码就可以快速的实现人脸检测与人脸识别。让“它”认得你。
人脸检测
人脸检测技术算得上是计算机视觉的基础级的技术之一。甚至在前深度学习时代,该技术就已经得到了很高程度的发展。在深度学习时代,人脸识别一般是利用卷积神经网络进行监督式学习,也就是通过让算法(神经网络)自己去发现规律的方式,创造出有用的卷积核(一种矩阵),然后利用其进行寻找图片和视频中的人脸。而在这之前,人们需要的则是自己去设计算法,寻找人脸。不过后来人们发明了一种近似于深度学习思路的人脸寻找算法,那就是haar算法。
这个算法简单点来说,就是计算一个区域内不同像素之间的灰度差别,来判断是不是人脸。原理就是一种有规律的图像,比如一个物体,无论光线明亮与否,其不同区域之间的像素差总是有一定规律的。就是凭借这种特殊的思路,科学家们第一次创造出了一种及其有效的人脸识别算法。而且其运算性能要求真的很低。甚至在树莓派1,2这种计算性能及其低的硬件设备上都能够快速运行。
OpenCV内部集成了人脸检测算法,并且OpenCV提供了训练好的人脸检测haar模型,使用yml保存。我们只需要简单的调用其中的类库就可以对照片或者视频进行人脸检测。下面我们就可以利用OpenCV中的摄像头调用和图片处理模块和人脸检测模块共同创建一个能够实时从摄像头中检测人脸数据,并将有关数据切割保存下来的程序。有了它,我们就可以创建一个带标签的人脸数据库,然后用于人脸识别。
代码实现
第一步:加载haar数据,训练好的数据可以去github下载,或者从我的github下载:https://github.com/FontTian/DS-Exhibitio
face_cascade =cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_cascade.load('./haarcascades/haarcascade_frontalface_default.xml')
第二步:我们需要调取摄像头,读取有关数据。同时由于我们需要实时显示,因此创建循环,在循环中不断调用获取摄像头中的图片,并进行后续处理。
# 获取摄像头
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
第三步:我们需要创建灰度图,然后使用人脸检测器对处理后的图像进行人脸检测。同时我们利用人脸检测器返回的数据,在原图片中绘制一个方框,并实时显示。
# 转换为灰度图
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)
这样一番操作后,我们就获得了一份人脸数据库,我们通过文件夹的名字来标识图片。
人脸识别
在完成人脸检测之后,我们就得到了一份可以用于人脸识别的人脸数据库。之后我们就可以调取OpenCV中的人脸识别方法进行人脸识别,但是人脸识别的方法是有很多种实现方式的。如果现在就要将深度学习免不了长篇大论。因此这里我们将会使用OpenCV中的三种非深度学习方法进行人脸识别,并详细介绍其使用,简单介绍其原理。
代码实现
OpenCV的人脸识别在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]
之后我们就可以调取不同人脸识别器来进行人脸识别了。OpenCV中自带三种人脸识别器——LBPH,EigenFace,Fisher。我们首先创建一个方法,来展示不同人脸识别器的判断结果和输出的置信度,置信度的范围选择我们在下一步会详细描述。
# 创建测试文件路径
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)
上面的几个步骤就是人脸识别器的一般步骤,本质上来说人脸识别器与一般的机器学习模型都是一样的。需要有标签的数据,然后来做分类。所以首先需要使用标记好的数据来进行训练,并用新的数据进行预测。而人脸识别器的关键则在于如何从人脸中提取特征,并使用特征进行人脸识别。这是人脸识别的永恒套路,以前如此,现在也如此。
EigenFace是基于PCA的人脸识别器,一般置信程度5000以下判断为可靠,PCA就是主成分分析,其在人脸识别中的作用就是提取出人脸的主要信息,以此来判断不同人。
LBPH是局部二值模式直方图,局部二值,指的是某一点像素与周围点的大小差别,0和1指的就是其大小关系。其核心原理类似于haar都是计算局部像素之间的差异关系来进行图像识别。
Fisher是基于线性判别的人脸识别器。线性判别广泛应用于机器学习的多个领域,分类,聚类,推荐中都存储在其身影。在这里其基本思想与PCA一致,都是降维获得该人脸的人脸特征然后通过人脸特征来进行人脸识别。
具体的置信度如下所示,我们如果直接选择打印labels,那么程序会直接从给出最佳结果,对于测试而言或许是足够的。但是使用置信度来进行检测才是更好地方法。
# 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)
现在运行上面的代就可以告诉我们最终结果了。下面就是运行结果
人脸识别,人脸检测的技术虽然一直都在发展,准确度和计算量都在不断提升。但是作为一项应用或者说一个领域,万变不离其宗。我们可以首先从OpenCV的几十行代码起步,逐步掌握深度学习下的人脸识别。
转载:https://blog.csdn.net/FontThrone/article/details/105314973