OpenCV与图像处理学习十七——OpenCV人脸检测(含代码)

一、人脸识别概要

一般而言,一个完整的人脸识别系统包含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 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'>
  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值