python人脸识别demo

现在人脸识别功能已经很成熟了,就想做个好玩的小功能:
只要某人来到摄像头前,就播放语音:某某某,你好!

分解一下实现步骤,大概就是:
摄像头采集图像,然后运行人脸识别算法,识别出人脸特征,进行人脸比对,并进行语音提示。

再说一下编程语言的选取,目前做人工智能的,用python的最多,就用它了。

具体实现的时候,大体分为下面几部分:

1,找一个人脸识别库,运行起来;
2,添加人脸图片;
3,使用摄像头获取图像;
4,文字转换为音频文件;
5,播放音频文件;
6,人脸与音频播放关联起来;
7,循环执行。


下面具体说明下实现步骤:

一,找一个人脸识别库,运行起来
    直接上网搜索,就有很多介绍推荐的,具体到能在自己的环境中运行起来,还是得试一试的。    我参考了几个例子后,选择的人脸识别库是:face_recognition,这是Github开源人脸识别项目。号称是世界上最简洁的人脸识别库,只需要几个接口,就完成了人脸识别功能。
    我下面的demo中,只调用了如下4个接口:
    定位图片中的所有人脸:

    face_locations(face_image,number_of_times_to_upsample=1,model="hog")

    识别人脸特征(128个特征向量):

    face_encodings(face_image, known_face_locations=None, num_jitters=1)

    人脸比对:

    compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6)

    人脸距离:

    face_distance(known_face_encodings, face_encoding_to_check)

    示例是快速上手一个新库的主要手段,从Face Recognition 官方库下载 源码 ,打开其中的 examples 目录,可以看到里面有各种示例,我是参考了 face_distance.py 、 find_faces_in_picture.py 和 facerec_ipcamera_knn.py 来熟悉这个 Face Recognition 库的使用。
        
    有了示例程序,然后就是搭建环境,主要就是安装几个依赖库:

    pip install numpy opencv-python
    pip install dlib
    pip install face_recognition

    再然后就是把demo跑起来了。
    文章后面我会提供完整代码。
    
二,添加人脸图片
demo目录结构如下图:

train中,存放的是底库图片,图片名就是底库人脸对应的人名,例如,lintax.jpg;
test中,存放的是测试图片,具体来说就是test.jpg。

audio目录中,存放的是音频文件。
main.py,就是python代码。
这里,我先把自己用手机拍的照片传进去,选一个有自己正脸的,裁剪得只有自己正脸的图片,编辑图片名称,做为人脸底库。然后换另一张多人的照片,看能否识别到自己。
开头试了下,竟然不能识别到!
做了如下几种调整后,可以识别了:
1,缩小底库图片;
    我是缩小到240*240,与例程中图像分辨率比较接近就行了。
2,缩小测试图片,也是缩放到与例程分辨率比较接近的程度。
然后,就能识别到自己了。
然而,出现了一个新问题,有别人也被识别到我了。    
考虑这个情况是比对的阈值选择问题,要更加严格一些。这里就需要来调整人脸比对的阈值;
    看这个人脸比对函数:

    compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6)

    参考face_recognition项目的中文说明:
    tolerance=0.6:两张脸之间有多少距离才算匹配。该值越小对比越严格,0.6是典型的最佳值。
    再看另一处说明:
    本项目的人脸识别是基于业内领先的C++开源库 dlib中的深度学习模型,用Labeled Faces in the Wild人脸数据集进行测试,有高达99.38%的准确率。但对小孩和亚洲人脸的识别准确率尚待提升。
    亚洲人脸,毫无疑问,我的脸是属于其中的。我也不会去搞什么人脸训练工作,就调整下阈值试试吧。
    试了下,把阈值改为0.4就可以了:
        tolerance=0.4
    到这里,主体功能算是可用了,剩下就是添枝加叶了。


三,使用摄像头获取图像
    就是如下两步,就获取到摄像头的图像了:

cam = cv2.VideoCapture(0)
ret,img = cam.read()

    接下来,就是把这个图片送入人脸识别,看看能否出结果。
    当然,前提是电脑上有个摄像头,并且可以正常工作。


四,文字转换为音频文件
    这里,我是采用的网络上的在线转换,见如下地址:
    https://app.xunjiepdf.com/text2voice/
    输入文字,然后转音频,下载,很方便的。


五,播放音频文件
    选什么音频播放库,我对比了几个,选择了playsound,因为它支持mp3,而前面我获取的音频文件就是mp3格式的。
    播放动作,也很方便,就是一句代码的事:

    playsound('./audio/hello_lintax.mp3')  

六,人脸与音频播放关联起来
    这个也简单,就是选匹配度最高的特征,对应到人名,再与音频播放关联起来:

    name = known_names[best_match]    #选匹配度最高的名字
    if(name.lower()=="lintax"):        #判断人名,与音频播放关联起来
        playsound('./audio/hello_lintax.mp3')  

七,循环执行
    就是在前面的一次性人脸识别之外,添加一个while循环。
    我这里也是简单处理,每5秒从摄像机捕获一帧图像,进行特征提取、比对,根据匹配情况确定是否播放语音。
    

八,源码
    整个demo的代码如下,当然,也可以直接下载(python人脸识别demo-深度学习文档类资源-CSDN下载):    

import face_recognition as fr
import cv2
import numpy as np
import os
import time
from playsound import playsound


path = "./train/"
known_names = []
known_name_encodings = []

print("train:")
images = os.listdir(path)
for file_name in images:
    print(file_name)
    image = fr.load_image_file(path + file_name)
    image_path = path + file_name
    encoding = fr.face_encodings(image)[0]
    #print(encoding)

    known_name_encodings.append(encoding)
    known_names.append(os.path.splitext(os.path.basename(image_path))[0].capitalize())

print(known_names)


#调用摄像头
cam = cv2.VideoCapture(0)
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
 
while True:
    print("cam.read")
    ret,img = cam.read()
    #展示捕获图片
    print("imshow")
    cv2.imshow('camera',img)
    k = cv2.waitKey(20)
    print("input key is ",k)
    if k == 27:  # esc 
        break
    
    #test_image = "./test/test.jpg"
    #image = cv2.imread(test_image)
    
    image = img
    # image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)


    print("face_locations:")
    face_locations = fr.face_locations(image)
    print("face_encodings:")
    face_encodings = fr.face_encodings(image, face_locations)

    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
        print("compare_faces:")
        matches = fr.compare_faces(known_name_encodings, face_encoding, tolerance=0.4)
        name = ""
        print(matches)

        print("face_distance:")
        face_distances = fr.face_distance(known_name_encodings, face_encoding)
        print(face_distances)
        best_match = np.argmin(face_distances)
        print(best_match)
        
        if matches[best_match]:
            name = known_names[best_match]
            print(name)
            if(name.lower()=="lintax"):
                playsound('./audio/hello_lintax.mp3')  
            
        cv2.rectangle(image, (left, top), (right, bottom), (0, 0, 255), 2)
        cv2.rectangle(image, (left, bottom - 15), (right, bottom), (0, 0, 255), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(image, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
        #cv2.imwrite("./output.jpg", image)

    time.sleep(5)
    
 
#释放资源
cam.release()
cv2.destroyAllWindows()

主要参考文章:
http://www.zzvips.com/article/210357.html
https://github.com/ageitgey/face_recognition
https://zhuanlan.zhihu.com/p/45827914    

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值