zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

用 dlib 计算人脸68个关键点

计算人脸 关键点 68 dlib
2023-06-13 09:13:08 时间

dlib 是较流行的人脸识别的开源库,使用c++编写,里面包含了许多的机器学习算法,。其官网链接是 dlib C++ Library - Machine Learning

dlib 也提供了python 接口,可通过pip 在线安装dlib,前提是要先安装VisualStudio, 还需先安装python库 cmake 和 boost。

dlib 提供了用于计算人脸68个关键点模型文件shape_predictor_68_face_landmarks.dat (需要单独下载)。68个点的位置如下:

import dlib
import cv2

# 与人脸检测相同,使用dlib自带的frontal_face_detector作为人脸检测器
detector = dlib.get_frontal_face_detector()

# 使用官方提供的模型构建特征提取器
predictor = dlib.shape_predictor(r'C:\Python39\Lib\site-packages\dlib\shape_predictor_68_face_landmarks.dat')
# cv2读取图片
img = cv2.imread("K:/image (46).png")
if img is None:
    print("the image file does not exist")

# 与人脸检测程序相同,使用detector进行人脸检测 dets为返回的结果
dets = detector(img, 1)
# 使用enumerate 函数遍历序列中的元素以及它们的下标
# 下标k即为人脸序号
# left:人脸左边距离图片左边界的距离 ;right:人脸右边距离图片左边界的距离
# top:人脸上边距离图片上边界的距离 ;bottom:人脸下边距离图片上边界的距离
for k, d in enumerate(dets):
    print("dets{}".format(d))
    print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
        k, d.left(), d.top(), d.right(), d.bottom()))

    # 使用predictor进行人脸关键点识别 shape为返回的结果
    shape = predictor(img, d)
    # 获取第一个和第二个点的坐标(相对于图片而不是框出来的人脸)
    print("Part 0: {}, Part 1: {} ...".format(shape.part(0), shape.part(1)))

    # 绘制特征点
    for index, pt in enumerate(shape.parts()):
        print('Part {}: {}'.format(index, pt))
        pt_pos = (pt.x, pt.y)
        cv2.circle(img, pt_pos, 1, (255, 0, 0), 2)
        #利用cv2.putText输出1-68
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, str(index+1),pt_pos,font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)

cv2.imshow('img', img)
k = cv2.waitKey()
cv2.destroyAllWindows()

示例图片:

还可以可以同一图片几张脸一起检测:

检测图片的代码稍做改动就可以检测摄像头实时视频:

import dlib
import cv2
import numpy as np

# 与人脸检测相同,使用dlib自带的frontal_face_detector作为人脸检测器
detector = dlib.get_frontal_face_detector()
# 使用官方提供的模型构建特征提取器
predictor = dlib.shape_predictor(r'C:\Python39\Lib\site-packages\dlib\shape_predictor_68_face_landmarks.dat')

font = cv2.FONT_HERSHEY_SIMPLEX

def faceDetect(img):
    global fdetector, predictor, font
    dets = detector(img, 1)
    # 使用enumerate 函数遍历序列中的元素以及它们的下标
    # k即为人脸序号
    # left:人脸左边距离图片左边界的距离 ;right:人脸右边距离图片左边界的距离
    # top:人脸上边距离图片上边界的距离 ;bottom:人脸下边距离图片上边界的距离
    for k, d in enumerate(dets):
        # print(f"dets{d}")
        # print(f"Detection {k}: Left: {d.left()} Top: {d.top()} Right: {d.right()} Bottom: {d.bottom()}")
        # 使用predictor进行人脸关键点识别 shape为返回的结果
        shape = predictor(img, d)
        # 获取第一个和第二个点的坐标(相对于图片而不是框出来的人脸)
        #print("Part 0: {}, Part 1: {} ...".format(shape.part(0), shape.part(1)))
        # 绘制特征点
        for index, pt in enumerate(shape.parts()):
            # print(f'Part {index}: {pt}')
            pt_pos = (pt.x, pt.y)
            cv2.circle(img, pt_pos, 1, (255, 0, 0), 2)
            #利用cv2.putText输出1-68
            # cv2.putText(img, str(index+1),pt_pos,font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)
    return img[:, : :-1, :] #mirrorred
    # return img
cameraCapture = cv2.VideoCapture(0)
print(cameraCapture)
fps = 60
size = int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))
#print(size)
videoWriter = cv2.VideoWriter("myvid.avi", cv2.VideoWriter_fourcc('X','V','I','D'), fps, size)
success, frame = cameraCapture.read()
numFramesRemaining = 1000* fps -1
while success and numFramesRemaining > 0:
    img = faceDetect(frame)
    videoWriter.write(img)
    cv2.imshow("my video", img)
    cv2.waitKey(1) #延迟
    success, frame = cameraCapture.read()
    numFramesRemaining -= 1
cameraCapture.release()
cv2.waitKey()
cv2.destroyAllWindows()