face_recognition人脸识别引擎安装及示例DEMO

admin 发布时间:2019-12-11 分类:分享 阅读:5352次 4 条评论

使用到了开源库 face_recognition,github地址:https://github.com/ageitgey/face_recognition

安装过程以Ubuntu及Python2.7为例:

apt-get update
apt-get install build-essential cmake
apt-get install libgtk-3-dev
apt-get install libboost-all-dev
#pip install dlibapt-get install python-pip
apt-get install python-pip
#pip install face_recognition
pip install --index https://mirrors.ustc.edu.cn/pypi/web/simple/  face_recognition

以上是插件的安装命令,安装完成后提示 Successfully,以下附上Python示例:

# coding:utf-8
import face_recognition
#输入已知图片1.jpg
known_image = face_recognition.load_image_file("1.jpg")
#输入待识别的图片2.jpg
unknown_image = face_recognition.load_image_file("2.jpg")
biden_encoding = face_recognition.face_encodings(known_image)[0]
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
results = face_recognition.compare_faces([biden_encoding], unknown_encoding)
#输出的results是一串Boolean值
print results

保存为facedemo.py文件,并在当前目录放置两张包含人脸信息的图片做对比,python facedemo.py 执行该demo。返回true表示两张图为同一人,否则匹配不通过。其中有几个API函数:

1、face_encodings 人脸解码:输入一张图片后,生成一个128维的特征向量,这是 人脸识别的依据。

2、compare_faces 人脸比对:人脸识别的核心,设置一个阈值,若两张人脸的特征向量的距离,在阈值范围之内,则认为其是同一个人,最后返回一个Boolean值的list。另外一个类似的函数是 face_distance 人脸特征向量距离,输出由Boolean对错改为数字number。

其他的函数请参考官方的API地址:https://face-recognition.readthedocs.io/en/latest/face_recognition.html 



python3的face_recognition教程

安装完python3之后,继续安装pip3:

apt install python3-pip
apt install cmake

再安装其他的开发插件等

pip3 install Flask

# 安装 OpenCV开发包
pip3 install opencv-python
# 安装最新的OpenCV 扩展
pip3  install opencv-contrib-python
pip3 install matplotlib

sudo apt-get update #安装依赖库
sudo apt-get install libhdf5-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libjasper-dev
sudo apt-get install libqt4-test
sudo apt-get install libqtgui4
sudo apt-get update
python3
import cv2 # 检查导入成功
cv2.__version__  # 检查cv2的版本

import cv2 可能会出现报错:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /home/pi/.local/lib/python3.7/site-packages/cv2/cv2.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: __atomic_fetch_add_8

需要运行:vim.tiny .bashrc

将该内容追加到文件底部:

export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1

使之生效:

source .bashrc


以下是完整简单的Python的Web实例,提供人脸注册及识别两个接口:

import os
from flask import Flask, request, redirect, url_for,jsonify
#from werkzeug import secure_filename
from pathlib import Path
import face_recognition
#头像文件保存路径
UPLOAD_FOLDER = '/root/face/' #linux
ALLOWED_EXTENSIONS = set(['jpg'])

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
@app.route('/face/register', methods=['POST'])

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
def get_file_extension(path): 
  return os.path.splitext(path)[1] 
def get_file_name(path): 
  return os.path.splitext(path)[0] 
  
# 人脸照片上传
@app.route('/face/uploader', methods=['POST'])
def face_uploader():
    userName = request.values.get('userName')
    file = request.files['file']
    if(not userName or not file):
        return jsonify({'code': 100,'msg':'error'})
    filepath = app.config['UPLOAD_FOLDER']
    if file and allowed_file(file.filename):
        #filename = secure_filename(file.filename) # 中文异常
        dirpath = app.config['UPLOAD_FOLDER']
        if not Path(dirpath).is_dir():
            os.mkdir(dirpath)
        filepath = os.path.join(dirpath, userName + get_file_extension(file.filename))
        file.save(filepath)
    return jsonify({'code': 200,'msg':'success','data':{'userName':userName,'filePath':filepath}})
    
# 上传照片识别 与上接口的人脸对比并返回名称
@app.route('/face/recog', methods=['POST'])
def face_recog():
    file = request.files['file']
    if(file is None):
        return jsonify({'code': 100,'msg':'error'})
    
    filepath = ''
    if file and allowed_file(file.filename):
        #filename = secure_filename(file.filename)
        dirpath = app.config['UPLOAD_FOLDER'] + "temp/"
        if not Path(dirpath).is_dir():
            os.mkdir(dirpath)
        filepath = os.path.join(dirpath, file.filename)
        file.save(filepath)
    print("temp filepath: " + filepath)
    unknown_image_file = face_recognition.load_image_file(filepath)
    unknown_image_encodeds = face_recognition.face_encodings(unknown_image_file)
    if len(unknown_image_encodeds) == 0:
        print("the upload img no face")
        return jsonify({'code': 101,'msg':'no face'})
    face_person_name = ''
    ## 查找已有的头像文件
    #names = [name for name in os.listdir(app.config['UPLOAD_FOLDER'])
    #    if os.path.isfile(os.path.join(app.config['UPLOAD_FOLDER'], name)) and
    #    name.endswith('.jpg')]
    images = os.listdir(app.config['UPLOAD_FOLDER'])
    # 遍历每张图像
    for image in images:
        current_path = os.path.join(app.config['UPLOAD_FOLDER'], image)
        if not image.endswith('.jpg') or not os.path.isfile(current_path):
            continue
        print("current_image filepath: " + current_path)
        current_image = face_recognition.load_image_file(current_path)
        # 将加载图像编码为特征向量
        current_image_encodeds = face_recognition.face_encodings(current_image)
        if len(current_image_encodeds) == 0:
            print("no face")
            continue
        # 将你的图像和图像对比,看是否为同一人
        result = face_recognition.compare_faces([unknown_image_encodeds[0]],current_image_encodeds[0])
        if result[0] == True:
            print("Matched: " + image)
            face_person_name = get_file_name(image)
        else:
            print("Not matched: " + image)
    ## 查找已有的头像文件
    #names = [name for name in os.listdir(app.config['UPLOAD_FOLDER'])
    #    if os.path.isfile(os.path.join(app.config['UPLOAD_FOLDER'], name)) and
    #    name.endswith('.jpg')]
    #known_face_list = []
    #for filename in names:
    #    face_image =
    #    face_recognition.load_image_file(os.path.join(app.config['UPLOAD_FOLDER'],
    #    filename))
    #    face_encoding = face_recognition.face_encodings(face_image)[0]
    #    known_face_list.append(face_encoding)
    #face_return =
    #face_recognition.compare_faces(known_face_list,unknown_image_file)
    
    return jsonify({'code': 200,'msg':'success','data':face_person_name})
if __name__ == "__main__":
    # 将host设置为0.0.0.0,端口5000 则外网用户也可以访问到这个服务
    app.run(host="0.0.0.0", port=5000, debug=True)

启动后通过5000端口访问:

接口1进行人脸照片上传,地址:http://*:5000/face/uploader ,使用form-data上传图片及人名。

接口2人脸对比并返回人名,地址:http://*:5000/face/recog ,使用form-data上传待识别的图片。


结合摄像头使用实时的人脸识别

下面的demo是python摄像头实时画面:

import cv2
cap = cv2.VideoCapture(0)
while True:
    ret,frame = cap.read()
    cv2.imshow('Video',frame)
    c = cv2.waitKey(1)
    if c == 27:
        break
cap.release()
cv2.destroyAllWindows()

下面的demo是python根据摄像头实时画面识别人脸:

# -*- coding: utf-8 -*-
import face_recognition
import cv2
video_capture = cv2.VideoCapture(0)
person_img = face_recognition.load_image_file("personname.jpg")
person_face_encoding = face_recognition.face_encodings(person_img)[0]
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
while True:
    ret, frame = video_capture.read()
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    if process_this_frame:
        face_locations = face_recognition.face_locations(small_frame)
        face_encodings = face_recognition.face_encodings(small_frame, face_locations)
        face_names = []
        for face_encoding in face_encodings:
            match = face_recognition.compare_faces([person_face_encoding], face_encoding)
            if match[0]:
                name = "personname"
            else:
                name = "unknown"
            face_names.append(name)
    process_this_frame = not process_this_frame
    for (top, right, bottom, left), name in zip(face_locations, face_names):
        top *= 4
        right *= 4
        bottom *= 4
        left *= 4
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255),  2)
        cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), 2)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left+6, bottom-6), font, 1.0, (255, 255, 255), 1)
    cv2.imshow('Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
video_capture.release()
cv2.destroyAllWindows()


已有4条留言

发表评论:

◎欢迎您的参与讨论。