云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

Dlib库教程(2):联合python的人脸检测、标记、识别

jxf315 2025-04-30 17:43:49 教程文章 3 ℃

1 说明

=====

1.1 准备篇《Dlib库教程(1):介绍、linux下的安装与避坑》

1.2 本次讲解Dlib库的强大的联合python的人脸检测、标记和识别功能。

1.3 熟悉Dlib库的python的API功能函数。

1.4 熟悉python编程相关知识,讲解思路清晰,注释仔细,干货满满,由浅入深,一秒入门。

1.5 图片来自今日头条正版免费图库,表示对女神的喜爱,致敬,仅供学习。

1.6 环境:python3.8+dlib19.21.99+opencv4.4.0+deepin-linux操作系统。

2 dlib+opencv+python的人脸检测、识别和标示

====================================

2.1 代码:

#人脸检测,画框和画68点特征显示

#第1步:导入模块
import dlib
import cv2

#第2步:模型加载
#这是人脸68点特征检测器模型,提前官网下载好
shape_predictor_path = '/home/xgj/Desktop/dlib/shape_predictor_68_face_landmarks.dat'  
#获取人脸分类器
detector = dlib.get_frontal_face_detector()    
#获取人脸 68 点特征检测器,进行人脸面部轮廓特征提取:
predictor = dlib.shape_predictor(shape_predictor_path)

#第3步:被检测图片
#载入被检测图片路径
imgpath ='/home/xgj/Desktop/dlib/pic/2.jpeg'
#读图片,cv.imread()共两个参数,第二个为如何读取图片,
#包括cv2.IMREAD_COLOR: 读入一个彩色图片
#img = cv2.imread(imgpath, cv2.IMREAD_COLOR)            
img = cv2.imread(imgpath)  #默认,等同于上面读取彩色图片

#这个是cv2特有的图片读取,需要转换,否则不是原图
b, g, r = cv2.split(img)
img2 = cv2.merge([r, g, b])
#侦测人脸
dets = detector(img2, 1)

#第4步:
for index, face in enumerate(dets):
    left = face.left()
    top = face.top()
    right = face.right()
    bottom = face.bottom()
    #在人脸上标示绿色方框
    cv2.rectangle(img,(left, top),(right, bottom),(0, 255, 0), 1)
    shape = predictor(img, face)

    for index, pt in enumerate(shape.parts()):
        pt_pos = (pt.x, pt.y)
        #标示人脸68个特征圆点
        cv2.circle(img, pt_pos, 1, (255, 0, 0), 1)

#第5步:
#展示已经人脸识别后的带有标示图片
cv2.imshow('pic',img)
cv2.namedWindow('pic',cv2.WINDOW_AUTOSIZE)
#窗口关闭设置
k = cv2.waitKey(0)
cv2.destroyAllWindows()

2.2 图

3 dlib+cv2+numpy法人脸检测和识别

===========================

3.1 代码

# encoding:utf-8
#代码来源
#https://blog.csdn.net/liuxiao214/article/details/83411820?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
#人脸检测,画框

import dlib
import numpy as np
import cv2

# 获得人脸矩形的坐标信息函数
def rect_to_bb(rect): 
    x = rect.left()
    y = rect.top()
    w = rect.right() - x
    h = rect.bottom() - y
    return (x, y, w, h)

# 图片大小调整函数
def resize(image, width=1200):  # 将待检测的image进行resize
    r = width * 1.0 / image.shape[1]
    dim = (width, int(image.shape[0] * r))
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
    return resized

# 人脸检测函数
def detect():
    #加载待检测的图片
    image_file = "/home/xgj/Desktop/dlib/pic/1.jpeg"
    image = cv2.imread(image_file)
    #调整大小
    image = resize(image, width=1200)
    #灰度转换
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    #dlib人脸检测器和人脸检测画框
    detector = dlib.get_frontal_face_detector()
    #dlib人脸检测矩形框4点坐标和对图像画人脸框
    rects = detector(gray, 1)

    #画框和输出文字
    for (i, rect) in enumerate(rects):
        (x, y, w, h) = rect_to_bb(rect)
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(image, "Face:{}".format(i + 1), (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
    
    #图片展示
    cv2.imshow("Output", image)
    cv2.waitKey(0)

if __name__ == "__main__":
    detect()

3.2 图

3.3 增加功能,标注68人脸特征点

=========================

3.3.1 代码

# encoding:utf-8

import dlib
import numpy as np
import cv2

# 获得人脸矩形的坐标信息
def rect_to_bb(rect): 
    x = rect.left()
    y = rect.top()
    w = rect.right() - x
    h = rect.bottom() - y
    return (x, y, w, h)

# 将包含68个特征的的shape转换为numpy array格式
def shape_to_np(shape, dtype="int"): 
    coords = np.zeros((68, 2), dtype=dtype)
    for i in range(0, 68):
        coords[i] = (shape.part(i).x, shape.part(i).y)
    return coords

# 将待检测的image进行resize
def resize(image, width=1200):  
    r = width * 1.0 / image.shape[1]
    dim = (width, int(image.shape[0] * r))
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
    return resized

#人脸检测、识别、标注68特征点
def feature():
    #加载被检测图片
    image_file = "/home/xgj/Desktop/dlib/pic/2.jpeg"
    image = cv2.imread(image_file)
    image = resize(image, width=1200)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    #加载dlib功能函数
    detector = dlib.get_frontal_face_detector()
    predictor = dlib.shape_predictor("/home/xgj/Desktop/dlib/shape_predictor_68_face_landmarks.dat")
    rects = detector(gray, 1)

    shapes = []
    #人脸检测、识别和画框
    for (i, rect) in enumerate(rects):
        shape = predictor(gray, rect)
        #获取特征点
        shape = shape_to_np(shape)
        #存入列表中
        shapes.append(shape)
        (x, y, w, h) = rect_to_bb(rect)
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(image, "Face: {}".format(i + 1), (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
    
    #获取68关键点并画圈标注
    for shape in shapes:
        for (x, y) in shape:
            cv2.circle(image, (x, y), 2, (0, 0, 255), -1)

    cv2.imshow("Output", image)
    cv2.waitKey(0)

if __name__ == "__main__":

    feature()

3.3.2 图

4 高级一点:视频实时检测人脸和标注

=============================

4.1 代码:

# coding=utf-8
#参考文章
#https://blog.csdn.net/m0_37477175/article/details/78151320?locationNum=2&fps=1&utm_medium=distribute.pc_relevant.none-task-blog-title-6&spm=1001.2101.3001.4242
#摄像头实时,人脸检测和画框和画弧,默认红色框和蓝色人脸特征线

import cv2
import dlib

# dlib模型加载
predictor_path = "/home/xgj/Desktop/dlib/shape_predictor_68_face_landmarks.dat"
# 初始化landmark
predictor = dlib.shape_predictor(predictor_path)
# 初始化dlib人脸检测器
detector = dlib.get_frontal_face_detector()

# 初始化dlib自带显示窗口
win = dlib.image_window()

# opencv加载视频文件
#cap = cv2.VideoCapture('/home/xxx.mp4')
#摄像头读取
cap = cv2.VideoCapture(0)
if cap.isOpened():
    print("Unable to connect to camera !")

#循环
while cap.isOpened():
    ret, cv_img = cap.read()
    if cv_img is None:
        break

    # RGB TO BGR
    img = cv2.cvtColor(cv_img, cv2.COLOR_RGB2BGR)
    #侦测和检测人脸
    dets = detector(img, 0)

    shapes = []
    for i, d in enumerate(dets):
        shape = predictor(img, d)
        shapes.append(shape)

    win.clear_overlay()
    win.set_image(img)
    if len(shapes)!= 0 :
        for i in range(len(shapes)):
            win.add_overlay(shapes[i])
    win.add_overlay(dets)

cap.release()

4.2 再高级一点的代码

# 调用摄像头,进行人脸捕获,和 68 个特征点的追踪
# 参考原作者,感谢原作者
# Author:   coneypo
# Blog:     http://www.cnblogs.com/AdaminXie
# GitHub:   https://github.com/coneypo/Dlib_face_detection_from_camera

#第1步:导入模块
import dlib         
import numpy as np  
import cv2
#时间模块用于截图保存后生成的文件名
import time
import timeit

#第2步:初始化
# 储存截图的目录
path_screenshots = "/home/xgj/Desktop/dlib/data/screenshots/"
# dlib模块加载
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('/home/xgj/Desktop/dlib/shape_predictor_68_face_landmarks.dat')

# 创建 cv2 摄像头对象
cap = cv2.VideoCapture(0)
# cap.set(propId, value)
# 设置视频参数,propId 设置的视频参数,value 设置的参数值
cap.set(3, 480)
# 截图 screenshots 的计数器
cnt = 0
#时间列表
time_cost_list = []

#第3步:
# cap.isOpened() 返回 true/false 检查初始化是否成功
while cap.isOpened():
    # cap.read()
    # 返回两个值:
    # 一个布尔值 true/false,用来判断读取视频是否成功/是否到视频末尾
    # 图像对象,图像的三维矩阵
    flag, im_rd = cap.read()

    # 每帧数据延时 1ms,延时为 0 读取的是静态帧
    k = cv2.waitKey(1)
    # 取灰度
    img_gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)
    # start point
    start = timeit.default_timer()
    # 人脸数
    faces = detector(img_gray, 0)
    # 待会要写的字体
    font = cv2.FONT_HERSHEY_SIMPLEX

    # 标 68 个点
    if len(faces) != 0:
        # 检测到人脸
        for i in range(len(faces)):
            landmarks = np.matrix([[p.x, p.y] for p in predictor(im_rd, faces[i]).parts()])

            for idx, point in enumerate(landmarks):
                # 68 点的坐标
                pos = (point[0, 0], point[0, 1])
                # 利用 cv2.circle 给每个特征点画一个圈,共 68 个
                cv2.circle(im_rd, pos, 2, color=(139, 0, 0))
                # 利用 cv2.putText 输出 1-68
                cv2.putText(im_rd, str(idx + 1), pos, font, 0.2, (187, 255, 255), 1, cv2.LINE_AA)

        cv2.putText(im_rd, "faces: " + str(len(faces)), (20, 50), font, 1, (0, 0, 0), 1, cv2.LINE_AA)
        # end point
        stop = timeit.default_timer()
        time_cost_list.append(stop - start)

    else:
        # 没有检测到人脸
        cv2.putText(im_rd, "no face", (20, 50), font, 1, (0, 0, 0), 1, cv2.LINE_AA)

    # 添加说明
    im_rd = cv2.putText(im_rd, "press 'S': screenshot", (20, 400), font, 0.8, (255, 255, 255), 1, cv2.LINE_AA)
    im_rd = cv2.putText(im_rd, "press 'Q': quit", (20, 450), font, 0.8, (255, 255, 255), 1, cv2.LINE_AA)

    # 按下 's' 键保存
    if k == ord('s'):
        cnt += 1
        cv2.imwrite(path_screenshots + "screenshot" + "_" + str(cnt) + "_" + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) + ".jpg", im_rd)

    # 按下 'q' 键退出
    if k == ord('q'):
        break

    # 窗口显示
    # 参数取 0 可以拖动缩放窗口,为 1 不可以
    cv2.namedWindow("camera", 0)
    #cv2.namedWindow("camera", 1)
    cv2.imshow("camera", im_rd)

# 释放摄像头
cap.release()
# 删除建立的窗口
cv2.destroyAllWindows()

5 备注:附注学习和复习opencv的色彩转换问题

====================================

5.1 代码

# -*- coding: utf-8 -*-
#熟悉opencv色彩转换问题
#代码所在终端打开输入
#python3.8 11.py /home/xgj/Desktop/dlib/pic/1.jpeg

import sys
import cv2 
import dlib

#采用skimage读取图片代码简单些,img全部为img
#from skimage import io  #add1

detector = dlib.get_frontal_face_detector()
win = dlib.image_window()

for f in sys.argv[1:]: 

  #img = io.imread(f)  #add2

  img = cv2.imread(f)
  
  #opencv的增加色彩转换,增加2行
  b, g, r = cv2.split(img)
  img1 = cv2.merge([r, g, b])
  
  dets = detector(img1,1) #使用detector进行人脸检测

  for i, d in enumerate(dets):
    x = d.left()
    y = d.top()
    w = d.right()
    h = d.bottom()   
    cv2.rectangle(img1, (x, y), (w, h), (0, 255, 0))
    print("({},{},{},{})".format( x, y, (w-x), (h-y)))

  win.set_image(img1)
  #io.imsave('/home/xgj/Desktop/dlib/P_Dlib_test.jpg',img)

  #增加2行色彩转换
  r, g, b = cv2.split(img1)
  img2 = cv2.merge([b, g, r])

  cv2.imwrite('/home/xgj/Desktop/dlib/P_Dlib_test.jpg',img2)
  
  #等待点击
  dlib.hit_enter_to_continue()

5.2 操作效果图

下一次讲,dlib的目标检测和实时视频的行人计数。

Tags:

最近发表
标签列表