百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

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

itomcoil 2025-04-27 14:17 5 浏览

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的目标检测和实时视频的行人计数。

相关推荐

Excel新函数TEXTSPLIT太强大了,轻松搞定数据拆分!

我是【桃大喵学习记】,欢迎大家关注哟~,每天为你分享职场办公软件使用技巧干货!最近我把WPS软件升级到了版本号:12.1.0.15990的最新版本,最版本已经支持文本拆分函数TEXTSPLIT了,并...

Excel超强数据拆分函数TEXTSPLIT,从入门到精通!

我是【桃大喵学习记】,欢迎大家关注哟~,每天为你分享职场办公软件使用技巧干货!今天跟大家分享的是Excel超强数据拆分函数TEXTSPLIT,带你从入门到精通!TEXTSPLIT函数真是太强大了,轻松...

看完就会用的C++17特性总结(c++11常用新特性)

作者:taoklin,腾讯WXG后台开发一、简单特性1.namespace嵌套C++17使我们可以更加简洁使用命名空间:2.std::variant升级版的C语言Union在C++17之前,通...

plsql字符串分割浅谈(plsql字符集设置)

工作之中遇到的小问题,在此抛出问题,并给出解决方法。一方面是为了给自己留下深刻印象,另一方面给遇到相似问题的同学一个解决思路。如若其中有写的不好或者不对的地方也请不加不吝赐教,集思广益,共同进步。遇到...

javascript如何分割字符串(javascript切割字符串)

javascript如何分割字符串在JavaScript中,您可以使用字符串的`split()`方法来将一个字符串分割成一个数组。`split()`方法接收一个参数,这个参数指定了分割字符串的方式。如...

TextSplit函数的使用方法(入门+进阶+高级共八种用法10个公式)

在Excel和WPS新增的几十个函数中,如果按实用性+功能性排名,textsplit排第二,无函数敢排第一。因为它不仅使用简单,而且解决了以前用超复杂公式才能搞定的难题。今天小编用10个公式,让你彻底...

Python字符串split()方法使用技巧

在Python中,字符串操作可谓是基础且关键的技能,而今天咱们要重点攻克的“堡垒”——split()方法,它能将看似浑然一体的字符串,按照我们的需求进行拆分,极大地便利了数据处理与文本解析工作。基本语...

go语言中字符串常用的系统函数(golang 字符串)

最近由于工作比较忙,视频有段时间没有更新了,在这里跟大家说声抱歉了,我尽快抽些时间整理下视频今天就发一篇关于go语言的基础知识吧!我这我工作中用到的一些常用函数,汇总出来分享给大家,希望对...

无规律文本拆分,这些函数你得会(没有分隔符没规律数据拆分)

今天文章来源于表格学员训练营群内答疑,混合文本拆分。其实拆分不难,只要规则明确就好办。就怕规则不清晰,或者规则太多。那真是,Oh,mygod.如上图所示进行拆分,文字表达实在是有点难,所以小熊变身灵...

Python之文本解析:字符串格式化的逆操作?

引言前面的文章中,提到了关于Python中字符串中的相关操作,更多地涉及到了字符串的格式化,有些地方也称为字符串插值操作,本质上,就是把多个字符串拼接在一起,以固定的格式呈现。关于字符串的操作,其实还...

忘记【分列】吧,TEXTSPLIT拆分文本好用100倍

函数TEXTSPLIT的作用是:按分隔符将字符串拆分为行或列。仅ExcelM365版本可用。基本应用将A2单元格内容按逗号拆分。=TEXTSPLIT(A2,",")第二参数设置为逗号...

Excel365版本新函数TEXTSPLIT,专攻文本拆分

Excel中字符串的处理,拆分和合并是比较常见的需求。合并,当前最好用的函数非TEXTJOIN不可。拆分,Office365于2022年3月更新了一个专业函数:TEXTSPLIT语法参数:【...

站长在线Python精讲使用正则表达式的split()方法分割字符串详解

欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是《在Python中使用正则表达式的split()方法分割字符串详解》。使用正则表达式分割字符串在Python中使用正则表达式的split(...

Java中字符串分割的方法(java字符串切割方法)

技术背景在Java编程中,经常需要对字符串进行分割操作,例如将一个包含多个信息的字符串按照特定的分隔符拆分成多个子字符串。常见的应用场景包括解析CSV文件、处理网络请求参数等。实现步骤1.使用Str...

因为一个函数strtok踩坑,我被老工程师无情嘲笑了

在用C/C++实现字符串切割中,strtok函数经常用到,其主要作用是按照给定的字符集分隔字符串,并返回各子字符串。但是实际上,可不止有strtok(),还有strtok、strtok_s、strto...