OpenCV与图像处理学习十七——OpenCV人脸检测(含代码)
- 一、人脸识别概要
- 1.1 人脸检测
- 1.2 人脸对齐(Face Alignment)
- 1.3 人脸特征提取(Face Feature Extraction)
- 1.4 人脸识别(Face Recognition)
- 二、人脸检测(不是识别)的代码
- 2.1 cv2.CascadeClassifier
- 2.2 dlib库
一、人脸识别概要
一般而言,一个完整的人脸识别系统包含4个主要组成部分,即人脸检测、人脸对齐(将侧脸或歪脸变成正面脸)、人脸特征提取以及人脸识别。
四部分流水线操作:
- 人脸检测在图像中找到人脸的位置;
- 人脸配准在人脸上找到眼睛、鼻子、嘴巴等面部器官的位置;
- 通过人脸特征提取将人脸图像信息抽象为字符串信息;
- 人脸识别将目标人脸图像与既有人脸比对计算相似度,确认人脸对应身份。
1.1 人脸检测
人脸检测算法的输入是一张图片,输出是人脸框坐标序列。一般情况下,输出的人脸坐标框为一个正朝上的正方形,但也有一些人脸检测技术输出是正朝上的矩形,或者是带旋转方向的矩形。
1.2 人脸对齐(Face Alignment)
根据人脸图像,自动定位出人脸五官关键点坐标的一项技术。
人脸对齐算法的输入是“一张人脸图片”加“人脸坐标框”,输出五官关键点的坐标序列。五官关键点的数量是预先设定好的一个固定数值,可以根据不同的语义来定义(常见的有5点、68点等)。
对人脸图像进行特征点定位,将得到的特征点利用仿射变换进行人脸矫正,若不矫正,非正面人脸进行识别的准确率不高。
1.3 人脸特征提取(Face Feature Extraction)
将一张人脸图像转化为一串固定长度的数值的过程。
具有表征某个人脸特点能力的数值串被称为“人脸特征(Face Feature)”
1.4 人脸识别(Face Recognition)
识别出输入人脸图对应身份的算法。
输入一个人脸特征,通过和注册在库中N个身份对应的特征进行逐个比对,找出 “一个” 与输入特征相似度最高的特征。将这个最高相似度和预设的阈值进行比较,如果大于阈值,则返回该特征对应的身份,否则返回 “不在库中” 。
二、人脸检测(不是识别)的代码
2.1 cv2.CascadeClassifier
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()
效果如下所示:
2.2 dlib库
ps:dlib库的安装可以自行百度。
dlib库是通过68特征点来识别人脸的:
# -*- coding:utf-8 -*-
import cv2
import dlib
import numpy as nppredictor_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-68font = cv2.FONT_HERSHEY_SIMPLEXcv2.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'>