OpenCV+Tensorflow实现实时人脸识别演示

小白学视觉

共 7793字,需浏览 16分钟

 · 2021-05-06

点击上方小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

本文转自|OpenCV学堂

Facenet网络介绍

FaceNet是谷歌提出的人脸识别模型,它跟其他人脸识别模型最大的一个不同就是它不是一个中间层输出,而是直接在欧几里德低维空间嵌入生成人脸特征,这个对以后的各种识别、分类、相似度比较都非常方便。相比其他的深度学习方法,FaceNet仅需要128个字节来表示一张脸。FaceNet网络设计目标任务有如下

1.验证-验证是否为同一张脸
2.识别-识别是否为同一个人
3.聚类-发现人脸具有相同之处的人

关于什么是神经网络嵌入,这个解释比较复杂,简单的说神经网络的嵌入学习可以帮助我们把离散变量表示为连续的向量,在低维空间找到最近邻,tensorflow中的word2vec就是用了嵌入。一旦嵌入神经网络训练好以后,目标任务就变得很简单:

人脸验证 – 就变成相似度比较问题
人脸识别 – 就变成KNN分类问题
人脸聚类 – 就变成通过K-Means可以完成的问题

相比其它的人脸识别网络,通过添加分类层实现人脸识别,在分类层之前输出的人脸特征数据动则就几千个维度数据,而且不能很好表达一张新的人脸。FaceNet使用三元损失函数基于LMNN训练输出128维的连续向量。三元损失包含了两个匹配人脸的指纹与一个不匹配的人脸指纹,损失函数训练的目标是训练它在匹配人脸指纹与不匹配人脸指纹之间距离margin足够大为止。人脸指纹来自人脸区域图像,没有经过对齐,只是结果简单的几何变换。整个网络架构与三元表示如下:

其中

对正负样本的选择需要选择难样本得到triplet,有利于更好的训练效果与模型收敛。

代码实现:

借用了Github上的一个tensorflow版本facenet实现,下载了预训练的facenet模型,基于得到embedding数据,这个会输出512个维度数据,进行比较实现人脸相似度计算。相似度计算采用了余弦相似度度量,两个嵌入数据距离为0表示完全一致,距离为1表示完全不同。0.5或者90度表示二者相互独立。

facenet预训练模型下载:
https://github.com/davidsandberg/facenet

加载模型与样本数据代码如下

with tf.Graph().as_default():
    with tf.Session() as sess:
        # Load the model
        facenet.load_model("D:/python/facenet/data/20180408-102900")
        # Get input and output tensors
        images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
        embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
        phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
        # Run forward pass to calculate embeddings
        images, names = load_face_labels()
        num_labels = len(names)
        feed_dict = {images_placeholder: images, phase_train_placeholder: False}
        labels_embeddings = sess.run(embeddings, feed_dict=feed_dict)

人脸比较的代码如下

def face_compare(face_image):
    # Run forward pass to calculate embeddings
    feed_dict = {images_placeholder: face_image, phase_train_placeholder: False}
    embedding_result = sess.run(embeddings, feed_dict=feed_dict)
    minDist = 1000000
    label_index = -1
    for i in range(num_labels):
        # 余弦相似
        dist = facenet.distance([labels_embeddings[i]], [embedding_result[0]], 1)
        if minDist > dist:
            label_index = i
            minDist = dist
    print("minDist: %1.4f"%minDist)
    if minDist > 0.25:
        return "unknown"
    if names[label_index] == 3:
        return "zhigang"
    if names[label_index] == 2:
        return "peter"
    if names[label_index] == 1:
        return "balvin"

OpenCV实时摄像头调用与输出

capture = cv.VideoCapture(0)
height = capture.get(cv.CAP_PROP_FRAME_HEIGHT)
width = capture.get(cv.CAP_PROP_FRAME_WIDTH)
out = cv.VideoWriter("D:/faces.mp4", cv.VideoWriter_fourcc('D''I''V''X'), 15,
                     (np.int(width), np.int(height)), True)
while True:
    ret, frame = capture.read()
    if ret is True:
        frame = cv.flip(frame, 1)
        cv.imshow("frame", frame)
        rgb = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
        result, bb = mtcnn_align_demo(rgb)
        if result is not None:
            name = face_compare(result)
            cv.rectangle(frame, (bb[0], bb[1]), (bb[2], bb[3]), (00255), 180)
            cv.putText(frame, name, (bb[0], bb[1]), cv.FONT_HERSHEY_SIMPLEX, 1.0, (02550), 28)
            cv.imshow("face recognition demo", frame)
            out.write(frame)
            cv.imwrite("D:/face_recognition.png", frame)
        c = cv.waitKey(10)
        if c == 27:
            break
    else:
        break
out.release()
capture.release()
cv.destroyAllWindows()

人脸数据采集

通过MTCNN进行人脸实时检测,采集了待比较的每个人的人脸数据,进行了数据采选,打上了标签。采集数据代码如下:

while True:
    ret, frame = capture.read()
    if ret is True:
        frame = cv.flip(frame, 1)
        cv.imshow("frame", frame)
        rgb = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
        result = detection(rgb)

        out.write(result)
        c = cv.waitKey(10)
        if c == 27:
            break
    else:
        break
cv.destroyAllWindows()

更详细的关于MTCNN可以看推荐阅读

运行效果

balvin与我




下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲
小白学视觉公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲
小白学视觉公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群


欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~


浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报