赞
踩
距离该系列的上一篇已经有一段时间了,在这段时间里,我们对人脸识别又有更深入的理解。这里就把我们这几天做的一部分东西总结一下。
python调用opencv库相当的简单,这里我们拿一个简单的程序来说下。
img = cv2.imread(image_name)
cv2.imshow("This is a window!", img) # img为上面读取图片的句柄
cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # img为上面读取图片的句柄
cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) → None
参数:
cv2.imwrite(filename, image[, params]) → retval
cv2.waitKey([delay]) → retval
功能:waitKey等待一个键盘输入事件,如果delay的值小于等于0,则无限等待,如果delay的值大于0,则等待delay(毫秒)。
face_cascade = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml')
haarcascade_frontalface_default.xml文件就是opencv在GitHub上共享出来的具有普适的训练好的数据,该文件是专门用来识别人脸的。我们可以直接的拿来使用(当然准确率并不是很高)。当然还有识别笑脸,眼睛的XML文件,可以自行使用XML相关文件。
文件地址:haarcascades
根据这些API结合使用,写一个简单的识别图片中的人脸,代码如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import cv2
# 识别人脸
def detectFaces(image_name):
# 读取图片
img = cv2.imread(image_name)
# 获得训练好的人脸的参数数据,这里直接使用GitHub上的默认值
face_cascade = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml')
# if语句:如果img维度为3,说明不是灰度图,先转化为灰度图gray,如果不为3,也就是2,原图就是灰度图
if img.ndim == 3:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
gray = img
# 探测人脸
faces = face_cascade.detectMultiScale(
gray,
scaleFactor = 1.15,
minNeighbors = 5,
minSize = (5, 5),
flags = cv2.CASCADE_SCALE_IMAGE
)
result = []
for (x, y, width, height) in faces:
result.append((x, y, x + width, y + height))
return result
def drawFaces(image_name):
faces = detectFaces(image_name)
if faces:
img = cv2.imread(image_name)
for (x1, y1, x2, y2) in faces:
cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0))
img_new_name = 'drawfaces_' + image_name
cv2.imwrite(img_new_name, img)
showImga(img_new_name)
else:
print("not found faces")
# 显示图片
def showImga(image_name):
img = cv2.imread(image_name)
cv2.imshow("Find Faces!", img)
cv2.waitKey(0)
if __name__ == '__main__':
drawFaces('test.jpg')
效果如下:
说道人脸识别,肯定要谈到数据和算法。在国际上已有的一些人脸数据库:
Yale人脸库(美国):
耶鲁大学,15人,每人11张照片,主要包括光照条件的变化,表情的变化等。
ORL人脸库(英国):
剑桥大学,40人,每人10张照片,包括表情变化,微小姿态变化,20%以内的尺度变化。
FERET人脸库(美国):
为 了促进人脸识别算法的研究和实用化,美国国防部的Counterdrug Technology Transfer Program(CTTP)发起了一个人脸识别技术(Face Recognition Technology 简称FERET)工程,它包括了一个通用人脸库以及通用测试标准。同一人的包括不同表情,光照,姿态和年龄的照片,到1997年,它已经包括了1000多 人的10000多张照片,并不断得到扩充,FERET定期对不同识别算法进行测试。
CMU PIE人脸库(美国):
卡 耐基梅隆大学,所谓PIE就是姿态(POSE),光照(ILLUMINATION)和表情(EXPRESSION)的缩写,CMU PIE人脸库建立于2000年11月,它包括来自68个人的40000张照片,其中包括了每个人的13种姿态条件,43种光照条件和4种表情下的照片,现 有的多姿态人脸识别的文献基本上都是在CMU PIE人脸库上测试的。
UMIST人脸库(英国):
曼彻斯特大学,20人,总共564张照片,姿态变化。
Bern人脸库(徳国):
Bern 大学,30人,每人10张灰度图像,主要包括人脸不同姿态的变化。
AR人脸库(美国):
Purdue 大学,126人的彩色照片,光照,尺度和表情变化。
经过我们的讨论和参考,我们选用了ORL人脸数据库作为第一阶段的测试数据库。
对于算法:主流的人脸检测方法基于以上特征采用Adaboost学习算法,Adaboost算法是一种用来分类的方法,它把一些比较弱的分类方法合在一起,组合出新的很强的分类方法。人脸检测过程中使用Adaboost算法挑选出一些最能代表人脸的矩形特征(弱分类器),按照加权投票的方式将弱分类器构造为一个强分类器,再将训练得到的若干强分类器串联组成一个级联结构的层叠分类器,有效地提高分类器的检测速度。
这里有必要在引用一下:浅析人脸检测之Haar分类器方法,看完这篇博客我相信很多人对Haar分类器方法有一定的了解。
当我们下载了ORL人脸库后,目录如下图所示,每个文件夹里面又有10张pgm图片
如果学过一点机器学习的同学,应该了解什么叫做数据集(一般会分为“训练数据”(training data)和“测试数据”(test data))训练数据用来跑模型,测试数据用来对该模型进行准确性判断。为了进行数据采集,我们可以自行拍照采集数据,不过本人嫌麻烦,就用opencv写了个用笔记本摄像头采来集数据的程序(有python版和C++版)。图片的格式已经预先处理好了,所以保存后可直接使用,当做训练数据。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import cv2
def camera():
capture = cv2.VideoCapture(0)
index = 1
while capture.isOpened():
# 返回一个元组,retval和image,retval用来检查是否读入成功
ok, frame = capture.read()
if not ok:
break;
else:
cv2.imshow("MyPicture", frame)
# 转为灰度图
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 改变图片大小
dst = cv2.resize(gray, (92, 112));
c = cv2.waitKey(100)
if c & 0xFF == ord('a'): # a拍照
filename = '%d.pgm' % index
index += 1
cv2.imwrite(filename, dst)
elif c & 0xFF == ord('q'): # q退出
break;
else:
continue
capture.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
camera()
为了方便程序导入图片和模型的建立对图片特征值的计算,我们需要事先写好CSV文件,存放图片的地址和相关图片对应的人物ID号,这样好进行区分。文件存放的路径最好放在att_faces文件目录下,方便读取。
文件内容如下:
代码如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
def createFile():
# Information
info = 'E:/WorkFor2017/ML/test_image/att_faces/s{0}/{1}.pgm;{2}\n'
# Input filename
filename = input('Enter file name: ')
fp = open(filename, 'w')
for i in range(1, 42):
for j in range(1, 11):
fp.write(info.format(i, j, i-1))
fp.close()
if __name__ == '__main__':
createFile()
这里说下特征值:
对于人来说,识别一张图片或许很简单,但是对于计算机来说并不简单,在计算机的“眼里”那些图片就是一堆毫无规律可循的数字。这时候想要识别一张图片到底是什么会变得异常困难。这时候特征值就起到了作用,计算机通过人脸识别算法计算出人脸的特征值,而不同的人脸特征值是不一样的,再次匹配一张人脸,只需要将计算出的人脸特征值和之前生成的特征值进行比对,就能对这个人进行识别。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。