一般而言,一个完整的人脸识别系统包含4个主要组成部分,即人脸检测、人脸对齐(将侧脸或歪脸变成正面脸)、人脸特征提取以及人脸识别。
四部分流水线操作:
人脸检测算法的输入是一张图片,输出是人脸框坐标序列。一般情况下,输出的人脸坐标框为一个正朝上的正方形,但也有一些人脸检测技术输出是正朝上的矩形,或者是带旋转方向的矩形。
根据人脸图像,自动定位出人脸五官关键点坐标的一项技术。
人脸对齐算法的输入是“一张人脸图片”加“人脸坐标框”,输出五官关键点的坐标序列。五官关键点的数量是预先设定好的一个固定数值,可以根据不同的语义来定义(常见的有5点、68点等)。
对人脸图像进行特征点定位,将得到的特征点利用仿射变换进行人脸矫正,若不矫正,非正面人脸进行识别的准确率不高。
将一张人脸图像转化为一串固定长度的数值的过程。
具有表征某个人脸特点能力的数值串被称为“人脸特征(Face Feature)”
识别出输入人脸图对应身份的算法。
输入一个人脸特征,通过和注册在库中N个身份对应的特征进行逐个比对,找出 “一个” 与输入特征相似度最高的特征。将这个最高相似度和预设的阈值进行比较,如果大于阈值,则返回该特征对应的身份,否则返回 “不在库中” 。
import cv2
# 读入图像
img = cv2.imread("image/3.png")
# 加载人脸特征,该文件在 python安装目录\Lib\site-packages\cv2\data 下
# 注意xml文件的路径一定要对
face_cascade = cv2.CascadeClassifier(r'image/haarcascade_frontalface_default.xml')
# 将读取的图像转为COLOR_BGR2GRAY,减少计算强度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 检测出的人脸个数
faces = face_cascade.detectMultiScale(gray, scaleFactor = 1.15, minNeighbors = 4, minSize = (5, 5))
print("Face : {0}".format(len(faces)))
print(faces)
# 用矩形圈出人脸的位置
for(x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.namedWindow("Faces")
cv2.imshow("Faces", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
ps:dlib库的安装可以自行百度。
dlib库是通过68特征点来识别人脸的:
# -*- coding:utf-8 -*-
import cv2
import dlib
import numpy as np
predictor_model = 'image/shape_predictor_68_face_landmarks/shape_predictor_68_face_landmarks.dat'
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_model)
# cv2读取图像
test_film_path = "image/3.png"
img = cv2.imread(test_film_path)
# 取灰度
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 人脸数rects
rects = detector(img_gray, 0)
print(rects[0])
for i in range(len(rects)):
landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()])
print(landmarks, type(landmarks))
for idx, point in enumerate(landmarks):
# 68点的坐标
pos = (point[0, 0], point[0, 1])
#print(idx+1, pos)
# 利用cv2.circle给每个特征点画一个圈,共68个
cv2.circle(img, pos, 3, color=(0, 255, 0))
# 利用cv2.putText输出1-68
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, str(idx+1), pos, font, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
# cv2.imwrite("result.png", img)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果如下所示:
68点坐标保存在一个np.martrix里:
[[ 95 137]
[ 98 162]
[104 187]
[108 212]
[117 235]
[131 255]
[149 272]
[170 285]
[192 289]
[215 285]
[235 270]
[253 251]
[266 229]
[272 205]
[276 180]
[283 156]
[285 131]
[101 114]
[116 106]
[134 107]
[153 110]
[172 117]
[209 117]
[227 109]
[246 106]
[265 105]
[282 113]
[190 135]
[191 153]
[191 172]
[192 189]
[177 199]
[184 203]
[192 205]
[201 203]
[208 199]
[125 135]
[136 127]
[151 127]
[163 139]
[149 143]
[135 143]
[219 138]
[230 127]
[245 126]
[257 134]
[247 142]
[232 142]
[161 235]
[172 226]
[185 219]
[193 222]
[200 219]
[212 226]
[224 235]
[213 247]
[201 252]
[193 252]
[184 252]
[172 247]
[168 235]
[185 231]
[193 232]
[200 232]
[217 235]
[201 235]
[193 236]
[185 235]] <class 'numpy.matrix'>