opencv入门基础(十)基于dlib进行人脸识别

opencv入门基础(十)基于dlib进行人脸识别

一.基础知识

dlib提供的高精度人脸识别算法是基于深度学习网络ResNet-34实现的,该网络基于300多万张照片进行训练,最终获得了人脸检测模型。
安装库的步骤顺序:cmake,boost,dlib(建议用.whl文件进行安装),face_recognition,以上进入到虚拟环境地址中用pip install xxx指令下载即可。
算法简介:

  1. 网络ResNet-34最终输出一个128D的描述子
  2. 网络ResNet-34训练过程的核心步骤:Triplets(三元组):
    2.1 每个triplet在训练的时候会读入3张图片(2张是同一人,1张是另一人),分别计算处各自人脸的128D描述子
    2.2 不断调整网络模型权重,使得同一个人的向量更近,不同人之间的向量更远

二.程序具体实现

通过比较图片之间欧氏距离的大小来看图片之间的相似度
预训练的RESNET-34的网络:
链接:https://pan.baidu.com/s/1uXYimH8midBPBAW2qqtUaw
提取码:yuw9
68点人脸关键点检测预训练网络
链接:https://pan.baidu.com/s/1gIIfbzBauLX3giBm2xLM8Q
提取码:9u32
复制这段内容后打开百度网盘手机App,操作更方便哦–来自百度网盘超级会员V2的分享

# 1 导入库
import cv2
import dlib
import numpy as np

# 定义:关键点编码为128D
def encoder_face(image, detector, predictor, encoder, upsample=1, jet=1):
    # 检测人脸
    faces = detector(image, upsample)
    # 对每张人脸进行关键点检测
    faces_keypoints = [predictor(image, face) for face in faces]  # 每张人脸的关键点
    return [ np.array(encoder.compute_face_descriptor(image, face_keypoint, jet)) for face_keypoint in faces_keypoints ]

# 定义:人脸比较,通过欧氏距离
def compare_faces(face_encoding, test_encoding):
    return list(np.linalg.norm(np.array(face_encoding) - np.array(test_encoding), axis=1))  # 计算两个特征向量的欧氏距离,axis=1表示按行向量处理

# 定义:人脸比较,输出对应的名称
def comapre_faces_order(face_encoding, test_encoding, names):
    distance = list(np.linalg.norm(np.array(face_encoding) - np.array(test_encoding), axis=1))
    return zip(*sorted(zip(distance, names)))

def main():
    # 2 读取4张图片
    img1 = cv2.imread("guo.jpg")
    img2 = cv2.imread("liu1.jpg")
    img3 = cv2.imread("liu2.jpg")
    img4 = cv2.imread("liu3.jpg")
    test = cv2.imread("liu4.jpg")
    # BGR to RGB
    img1 = img1[:, :, ::-1]
    img2 = img2[:, :, ::-1]
    img3 = img3[:, :, ::-1]
    img4 = img4[:, :, ::-1]
    test = test[:, :, ::-1]

    img_names = ["guo,jpg", "liu1.jpg", "liu2.jpg", "liu3.jpg"]

    # 3  加载人脸检测器
    detector = dlib.get_frontal_face_detector()

    # 4 加载关键点的检测器
    predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

    # 5 加载人脸特征编码模型
    encoder = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")

    # 6 调用方法:128D特征向量输出
    img1_128D = encoder_face(img1, detector, predictor, encoder)[0]  # [0]指的是每张图片的第一个人脸,因为一张图片上可能有很多人脸
    img2_128D = encoder_face(img2, detector, predictor, encoder)[0]
    img3_128D = encoder_face(img3, detector, predictor, encoder)[0]
    img4_128D = encoder_face(img4, detector, predictor, encoder)[0]
    test_128D = encoder_face(test, detector, predictor, encoder)[0]

    four_images_128D = [img1_128D, img2_128D, img3_128D, img4_128D]

    # 7 调用方法:比较人脸,计算特征向量之间的距离,判断是否为同一人
    distance = compare_faces(four_images_128D, test_128D)
    print(distance)  # liu4.jpg图片和前面四张图片的欧氏距离
    # [0.668335014766784, 0.39842920068271925, 0.34284593679403474, 0.33843979733950336]可见与第一张guo.jpg距离最大,最不相似
    distance, name = comapre_faces_order(four_images_128D, test_128D, img_names)

    print("\n")
    print("distance: {}, \n names: {} ".format(distance, name))
# distance: (0.33843979733950336, 0.34284593679403474, 0.39842920068271925, 0.668335014766784), 
# names: ('liu3.jpg', 'liu2.jpg', 'liu1.jpg', 'guo,jpg') 
# 这样就可以看到test图片和另外4张图片的欧氏距离和图片名称的对应关系了
if __name__ == '__main__':
    main()

结果为(可以用自己找到的照片进行验证,只需改动程序中的图片名称即可):在这里插入图片描述

三.face_recognition实现的人脸识别

主要用到的函数:

  1. face_distance(face_encodings,face_to_compare)计算两个人脸之间的距离
  2. face_locations(img,number_of_times_to_upsample=1,model=“hog”)用于查看图片中有几张人脸,返回包括人脸位置的数组
  3. face_landmarks(face_image,face_locations=None,model=“large”)用于检索人脸关键点
  4. face_encodings(face_iamge,known_face_locations=None,num_jitters=1,model=“small”)将关键点进行128D的编码
  5. compare_faces(known_face_encodings,face_encoding_to_check,tolerance=0.6)比较两张图片是不是一个人,是则返回True,不是则返回False,0.6为相似判别阈值
# 1 加载库
import cv2
import numpy as np
import face_recognition

# 2 加载图片
liu = cv2.imread("liu.jpeg")
guo = cv2.imread("guo.jpg")

# 3 BGR 转 RGB
liu_RGB = liu[:, :, ::-1]
guo_RGB = guo[:, :, ::-1]

# 4 检测人脸
liu_face = face_recognition.face_locations(liu_RGB)
guo_face = face_recognition.face_locations(guo_RGB)

# 5 人脸特征编码
liu_encoding = face_recognition.face_encodings(liu_RGB, liu_face)[0]
guo_encoding = face_recognition.face_encodings(guo_RGB, guo_face)[0]

# 6 把所有人脸放在一起,当做数据库使用
encodings = [liu_encoding, guo_encoding]
names = ["liu de hua", "guo fu cheng"]

# 7 打开摄像头,读取视频流
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    raise  IOError("Camera Error !")

while True:
    ret, frame = cap.read()
    frame = cv2.resize(frame, (0,0), fx=0.5, fy=0.5)
    # 8 BGR 转 RGB
    frame_RGB = frame[:, :, ::-1]
    # 9 人脸检测
    faces_locations = face_recognition.face_locations(frame_RGB)
    # 10 人脸特征编码
    faces_encodings = face_recognition.face_encodings(frame_RGB, faces_locations)
    # 11 与数据库中的所有人脸进行匹配
    for (top, right, bottom, left), face_encoding in zip(faces_locations, faces_encodings):  # zip的作用是组合数据,让两个数据相对应
        # 12 进行匹配
        matches = face_recognition.compare_faces(encodings, face_encoding)
        # 13 计算距离
        distances = face_recognition.face_distance(encodings, face_encoding)
        min_distance_index = np.argmin(distances) # 0, 1, 2
        # 14 判断:如果匹配,获取名字
        name = "Unknown"
        if matches[min_distance_index]:
            name = names[min_distance_index]
        # 15 绘制人脸矩形框
        cv2.rectangle(frame, (left, top), (right, bottom), (0,255,0), 3)
        # 16 绘制、显示对应人脸的名字
        cv2.rectangle(frame, (left, bottom - 30),(right, bottom), (0,0,255), 3)
        # 17 显示名字
        cv2.putText(frame, name, (left+10 , bottom-10), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 1)
    # 18 显示整个效果
    cv2.imshow("face recognition", frame)
    # 19 判断 Q , 退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
# 20 关闭所有资源
cap.release()
cv2.destroyAllWindows()

在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值