OpenCV实现人脸检测和68点定位 您所在的位置:网站首页 opencv画图卡掉 OpenCV实现人脸检测和68点定位

OpenCV实现人脸检测和68点定位

2023-08-28 03:22| 来源: 网络整理| 查看: 265

人脸对比是现在比较常用的功能,比如出租车司机人脸与司机驾照照片对比,门禁系统中进入者的人脸与人脸库中的人脸进行对比。要实现人脸对比,首先要实现的是人脸检测,在摄像头拍摄到的一张图片中,正确的检测到人脸的位置,并且将人脸提取出来。

目录

1 原理先知

        1.1 68点标定和OpenCV绘点

        1.2 编码设计思路

        1.3 OpenCV画图函数介绍

2 环境说明

3 实验内容

4 步骤详解

        4.1 OpenCV实现人脸检测

        4.2 人脸68点定位

1 原理先知 1.1 68点标定和OpenCV绘点

考虑到免费开源,OpenCV 就可以很好的实现这个功能。 这里使用OpenCV提供好的人脸分类模型xml:haarcascade_frontalface_alt_tree.xml。 同时利用Dlib官方给的人脸识别预测器“shape_predictor_68_face_landmarks.dat”进行68点标定(利用OpenCV进行图像化处理,在人脸上画出68个点,并标明序号)。

注:OpenCV人脸分类模型xml及Dlib人脸识别预测器下载地址https://pan.baidu.com/s/1gZfYupoW9Zo_2lVV524cWA  提取码:w536 

人脸68点定位工作内容主要以下两大块:68点标定 和 OpenCV绘点

68点标定:dlib提供了训练好的模型,可以识别人脸的68个特征点OpenCV绘点:画圆函数cv2.circle() 和 输出字符串函数 cv2.putText() 1.2 编码设计思路 调用dlib库来进行人脸识别,调用预测器“shape_predictor_68_face_landmarks.dat”进行68点标定存入68个点坐标利用cv2.circle来画68个点利用cv2.putText()函数来画数字1-68 1.3 OpenCV画图函数介绍 画圆 cv2.circle( img, (p1,p2), r, (255,255,255) )img 图片对象(p1,p2) 圆心坐标r 半径(255,255,255)  颜色数组输出字符 cv2.putText( img,"test", (p1,p2), font, 4, (255,255,255), 2, cv2, LINE_AA )img 图像对象"test"  需要打印的字符 text(数字的话可以利用str()转成字符)(p1,p2) 坐标 textOrgfont 表示字体 fontFace(注意这里 font = cv2.FONT_HERSHEY_SIMPLEX)4 表示字号 fontScale(255,255,255) 颜色数组2 线宽 thicknessLINE_AA 线条种类 line_type; 关于颜色数组:(255,255,255), (蓝色,绿色,红色),每个值都是0-255。比如:蓝色(255,0,0),紫色(255,0,255) 2 环境说明 Linux Ubuntu 16.04Python 3.6PyCharm Community2018Opencv-python 3.4.0.12 3 实验内容 使用haarcascade_frontalface_alt_tree.xml人脸分类模型检测人脸。利用Dlib官方给的人脸识别预测器“shape_predictor_68_face_landmarks.dat”进行68点标定,利用OpenCV进行图像化处理,在人脸上画出68个点,并标明序号。 4 步骤详解 4.1 OpenCV实现人脸检测

首先将图片转换成灰色:使用 OpenCV 的 cvtColor() 转换图片颜色。

import cv2 filepath = "/data/opencv12/mv.jpg" img = cv2.imread(filepath) # 转换灰色,目的是在人脸检测时排除色彩的干扰 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 显示图像 cv2.imshow("original", img) cv2.imshow("Image", gray) cv2.waitKey(0) cv2.destroyAllWindows()

之后使用训练分类器查找人脸:在使用 OpenCV 的人脸检测之前,需要一个人脸训练模型,格式是 xml 的,本实验中使用的是 OpenCV 提供好的人脸分类模型 xml:haarcascade_frontalface_alt_tree.xml。 Haar 特征分类器就是一个 XML 文件,该文件中会描述人体各个部位的Haar特征值。包括人脸、眼睛、嘴唇等等。 OpenCV中人脸检测使用的是 detectMultiScale函数。它可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示)。

# 加载OpenCV人脸识别分类器 face_detector = cv.CascadeClassifier("haarcascade_frontalface_alt_tree.xml") # 调用函数识别人脸 faceRects = classifier.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32))

最后在图片上画矩形:使用 OpenCV 的 rectangle() 绘制矩形。

color = (0, 255, 0) if len(faceRects): # 大于0则检测到人脸 for faceRect in faceRects: # 单独框出每一张人脸 x, y, w, h = faceRect # x、y表示坐标;w、h表示矩形宽和高 # 框出人脸 cv2.rectangle(img, (x, y), (x + h, y + w), color, 2) # 左眼 cv2.circle(img, (x + w // 4, y + h // 4 + 30), min(w // 8, h // 8),color) #右眼 cv2.circle(img, (x + 3 * w // 4, y + h // 4 + 30), min(w // 8, h // 8),color) #嘴巴 cv2.rectangle(img, (x + 3 * w // 8, y + 3 * h // 4),(x + 5 * w // 8, y + 7 * h // 8), color)

OpenCV实现人脸检测完整代码如下:

import cv2 filepath = "/data/opencv12/mv.jpg" img = cv2.imread(filepath) cv2.imshow("original", img) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) classifier = cv2.CascadeClassifier("/data/opencv12/haarcascade_frontalface_alt_tree.xml") faceRects = classifier.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32)) color = (0, 255, 0) if len(faceRects): for faceRect in faceRects: x, y, w, h = faceRect cv2.rectangle(img, (x, y), (x + h, y + w), color, 2) cv2.circle(img, (x + w // 4, y + h // 4 + 30), min(w // 8, h // 8),color) cv2.circle(img, (x + 3 * w // 4, y + h // 4 + 30), min(w // 8, h // 8),color) cv2.rectangle(img, (x + 3 * w // 8, y + 3 * h // 4),(x + 5 * w // 8, y + 7 * h // 8), color) cv2.imshow("image", img) cv2.waitKey(0) cv2.destroyAllWindows()

OpenCV实现人脸检测运行结果如下所示。

4.2 人脸68点定位

除了使用 OpenCV 实现人脸检测之外,也可以借助比 OpenCV 更加精准的图片人脸检测 Dlib 库实现人脸 68 点定位。

首先导入需要调用的库。

import dlib #人脸识别的库dlib from PIL import Image #图像处理的库PIL import numpy as np #数据处理的库numpy import cv2 #图像处理的库OpenCv

之后读取图片,并将图片转换为灰度图。

path = "/data/opencv12/mv.jpg" img = cv2.imread(path) cv2.imshow("original", img) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

接下来读取训练模型,就可以检测脸部 68 特征点。

# 人脸分类器 detector = dlib.get_frontal_face_detector() # 获取人脸检测器 predictor = dlib.shape_predictor("/data/opencv12/shape_predictor_68_face_landmarks.dat")

最后在人脸上遍历所有检测点并打上标注,并标注 1-68 数字。

rects = detector(gray, 0) for i in range(len(rects)): landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()]) # 寻找人脸的68个标定点 # 遍历所有点,打印出其坐标,并圈出来,并标注1-68数字 for idx, point in enumerate(landmarks): pos = (point[0, 0], point[0, 1]) # 利用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.3, (0, 0, 255), 1, cv2.LINE_AA)

人脸68点定位完整代码如下:

import cv2 import dlib import numpy as np path = "/data/opencv12/mv.jpg" img = cv2.imread(path) cv2.imshow("original", img) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor("/data/opencv12/shape_predictor_68_face_landmarks.dat") rects = detector(gray, 0) for i in range(len(rects)): landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()]) for idx, point in enumerate(landmarks): pos = (point[0, 0], point[0, 1]) cv2.circle(img, pos, 3, color=(0, 255, 0)) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(img, str(idx+1), pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA) cv2.imshow("imgdlib", img) cv2.waitKey(0) cv2.destroyAllWindows()

人脸68点定位运行结果如下所示。 可以发现,dlib检测到人脸包括双眼、鼻子、嘴巴在内并用68点标注过的图片如下所示,并可以精准的定位检测人脸。

欢迎留言,一起学习交流~

感谢阅读

END


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有