简介

Dlib是一个包含机器学习算法的C++开源工具包。Dlib可以帮助您创建很多复杂的机器学习方面的软件来帮助解决实际问题。目前Dlib已经被广泛的用在行业和学术领域,包括机器人,嵌入式设备,移动电话和大型高性能计算环境。

Dlib是开源的、免费的;相关资料如下: 

官网:http://dlib.net/

中文官网:https://dlib.net.cn/?p=33

python API:http://dlib.net/python/

相关文件:http://dlib.net/files/      【包括安装包,模型权重等】

 

主要特点

1. 完善的文档:每个类每个函数都有详细的文档,并且提供了大量的示例代码,如果你发现文档描述不清晰或者没有文档,告诉作者,作者会立刻添加。

2. 可移植代码:代码符合 ISO C++ 标准,不需要第三方库支持,支持 win32、Linux、Mac OS X、Solaris、HPUX、BSDs 和 POSIX 系统

3. 线程支持:提供简单的可移植的线程 API

4. 网络支持:提供简单的可移植的 Socket API 和一个简单的 Http 服务器

5. 图形用户界面:提供线程安全的 GUI API

6. 数值算法:矩阵、大整数、随机数运算等

7. 机器学习算法:

8. 图形模型算法:

9. 图像处理:支持读写 Windows BMP 文件,不同类型色彩转换

10. 数据压缩和完整性算法:CRC32、Md5、不同形式的 PPM 算法

11. 测试:线程安全的日志类和模块化的单元测试框架以及各种测试 assert 支持

12. 一般工具:XML 解析、内存管理、类型安全的 big/little endian 转换、序列化支持和容器类

 

安装 

之前已经安装过,稍微有点麻烦,

后续如果重新安装再更新吧,可参考下面的资料

 

人脸应用

dlib 在人脸方面较为常用,可实现  人脸检测、人脸关键点检测、人脸对齐、人脸识别、人脸聚类、目标追踪 等等;

效果一般

 

人脸检测

检测一张图上的人脸,可有多个人脸

import cv2
import dlib

cap = cv2.VideoCapture(0)
detector = dlib.get_frontal_face_detector()     # 人脸检测器
win = dlib.image_window()       # 显示窗口

while 1:
    ret, img = cap.read()
    # 1 表示将图片放大一倍,便于检测到更多人脸
    dets = detector(img, 1)
    print('检测到了 %d 个人脸' % len(dets))
    for i, d in enumerate(dets):
        print('- %d:Left %d Top %d Right %d Bottom %d' % (i, d.left(), d.top(), d.right(), d.bottom()))

    win.clear_overlay()
    win.set_image(img)
    win.add_overlay(dets)
    # dlib.hit_enter_to_continue()


    # -1 表示人脸检测的判定阈值
    # scores 为每个检测结果的得分,idx 为人脸检测器的类型
    dets, scores, idx = detector.run(img, 1, -1)
    for i, d in enumerate(dets):
        print('%d:score %f, face_type %f' % (i, scores[i], idx[i]))
    win.clear_overlay()
    win.set_image(img)
    win.add_overlay(dets)
    dlib.hit_enter_to_continue()

 

人脸关键点检测

先进行人脸检测,再对每个人脸进行关键点检测;

dlib库采用68点位置标志人脸重要部位,比如18-22点标志右眉毛,51-68标志嘴巴

 

需要下载 shape_predictor_68_face_landmarks.dat,      【地址为上面的相关文件链接】

import cv2
import time
import dlib

detector = dlib.get_frontal_face_detector()
predictor_path = 'shape_predictor_68_face_landmarks.dat'
predictor = dlib.shape_predictor(predictor_path)
win = dlib.image_window()
cap = cv2.VideoCapture(0)

while 1:
    ret, img = cap.read()

    win.clear_overlay()
    win.set_image(img)
    # 1 表示将图片放大一倍,便于检测到更多人脸
    dets = detector(img, 1)
    print('检测到了 %d 个人脸' % len(dets))
    for i, d in enumerate(dets):
        print('- %d: Left %d Top %d Right %d Bottom %d' % (i, d.left(), d.top(), d.right(), d.bottom()))
        shape = predictor(img, d)        # 关键点检测
        # 第 0 个点和第 1 个点的坐标
        print('Part 0: {}, Part 1: {}'.format(shape.part(0), shape.part(1)))
        win.add_overlay(shape)

    win.add_overlay(dets)
    time.sleep(0.1)            # 加上这句,不然太快了,直接 clear_overlay 了
    # dlib.hit_enter_to_continue()

 

人脸对齐

import dlib
import face_recognition
import math
import numpy as np
import cv2

cap = cv2.VideoCapture(0)

def rect_to_bbox(rect):
    """获得人脸矩形的坐标信息"""
    # print(rect)
    x = rect[3]; y = rect[0]
    w = rect[1] - x; h = rect[2] - y
    return (x, y, w, h)

def face_alignment(faces):
    '''人脸对齐的计算都在这个函数'''
    # 关键点检测
    predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
    faces_aligned = []
    for face in faces:
        rec = dlib.rectangle(0, 0, face.shape[0], face.shape[1])
        shape = predictor(np.uint8(face), rec)
        # left eye, right eye, nose, left mouth, right mouth
        # order = [36, 45, 30, 48, 54]
        # for j in order:
        #     x = shape.part(j).x
        #     y = shape.part(j).y
        # 计算两眼的中心坐标
        eye_center = ((shape.part(36).x + shape.part(45).x) * 1. / 2, (shape.part(36).y + shape.part(45).y) * 1. / 2)
        dx = (shape.part(45).x - shape.part(36).x)
        dy = (shape.part(45).y - shape.part(36).y)
        # 计算角度
        angle = math.atan2(dy, dx) * 180. / math.pi
        # 计算仿射矩阵
        RotateMatrix = cv2.getRotationMatrix2D(eye_center, angle, scale=1)
        # 进行仿射变换,即旋转
        RotImg = cv2.warpAffine(face, RotateMatrix, (face.shape[0], face.shape[1]))
        faces_aligned.append(RotImg)
    return faces_aligned

while 1:
    ret, img = cap.read()
    cv2.imshow('org', img)
    cv2.waitKey(3)

    # 第一步,人脸检测,获取位置
    face_locations = face_recognition.face_locations(img)
    # 提取人脸区域的图片并保存
    src_faces = []
    for (i, rect) in enumerate(face_locations):
        (x, y, w, h) = rect_to_bbox(rect)
        detect_face = img[y:y + h, x:x + w]
        src_faces.append(detect_face)

    # 第二步, 人脸对齐
    faces_aligned = face_alignment(src_faces)   # 就这一句
    face_num = 0
    for faces in faces_aligned:
        face_num = face_num + 1
        faces = cv2.cvtColor(faces, cv2.COLOR_RGBA2BGR)
        cv2.imshow('align', faces)
    cv2.waitKey(3)

 

人脸识别

Dlib 将每张人脸映射为一个128维的向量,当两个向量之间的Euclidean距离小于0.6时,可以认为属于同一个人;

以上判定标准在LFW(Labeled Faces in the Wild)数据集上可以获得99.38%的识别准确率

import dlib
from imageio import imread
import glob
import numpy as np

detector = dlib.get_frontal_face_detector()
predictor_path = 'shape_predictor_68_face_landmarks.dat'
predictor = dlib.shape_predictor(predictor_path)
face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat'
facerec = dlib.face_recognition_model_v1(face_rec_model_path)
labeled = glob.glob('img/labeled/*.jpg')
labeled_data = {}
unlabeled = glob.glob('img/unlabeled/*.jpg')

def distance(a, b):
    return np.linalg.norm(np.array(a) - np.array(b), ord=2)

# 读取标注图片并保存对应的128向量
for path in labeled:
    img = imread(path)
    name = path.split('/')[1].rstrip('.jpg')
    dets = detector(img, 1)
    # 这里假设每张图只有一个人脸
    shape = predictor(img, dets[0])
    face_vector = facerec.compute_face_descriptor(img, shape)
    labeled_data[name] = face_vector

# 读取未标注图片,并和标注图片进行对比
for path in unlabeled:
    img = imread(path)
    name = path.split('/')[1].rstrip('.jpg')
    dets = detector(img, 1)
    # 这里假设每张图只有一个人脸
    shape = predictor(img, dets[0])
    face_vector = facerec.compute_face_descriptor(img, shape)
    matches = []
    for key, value in labeled_data.items():
        d = distance(face_vector, value)
        if d < 0.6:
            matches.append(key + ' %.2f' % d)
    print('{}:{}'.format(name, ';'.join(matches)))

我亲测了一下,搞了几个明星脸,或许是明星整容、化妆太厉害,效果一般

 

人脸聚类

方法和原理基本同人脸识别,不再赘述,参考 资料1 

 

 

 

 

参考资料:

https://zhuanlan.zhihu.com/p/44169338  Dlib快速入门      【基本上看这篇就够了

https://blog.csdn.net/liuxiao214/article/details/83411820?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-83411820-blog-78347484.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-83411820-blog-78347484.pc_relevant_default&utm_relevant_index=1  【Dlib】人脸检测、特征点检测、人脸对齐、人脸识别

 

https://blog.csdn.net/hongbin_xu/article/details/78347484  python dlib学习(一):人脸检测

https://www.aiuai.cn/aifarm1531.html  Dlib库 - 人脸关键点检测与对齐实现    【dlib  PIL 实现的人脸对齐】

https://blog.csdn.net/qq_42839007/article/details/104015954?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.add_param_isCf  python如何安装Dlib库