欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

学习笔记:python人脸识别3-通过web客户端摄像头识别人脸

程序员文章站 2022-07-12 20:53:38
...

在web登录人脸认证中,需要通过浏览器调用客户端电脑或手机的摄像头,再把获取的图像发送到服务端识别认证,这是通过人脸登录的基础。

本次测试采用html5调用客户端浏览器摄像头,获取图像发送到服务端认证

 html5获取客户端摄像头画面,点击验证后,把客户端截屏数据进行base64编码,并模拟form提交数据,服务端获取post的form数据后,base64解码并存储在服务器临时图片文件,再把这个文件作为输入进行人脸识别。

1. checkface.html 发起认证

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        video {
            border: 1px solid #ccc;
            display: block;
            margin: 0 0 20px 0;
            float: left;
        }

        #canvas {
            margin-top: 20px;
            border: 1px solid #ccc;
            display: block;
        }
    </style>
</head>
<body>
    <video id="video" width="500" height="400" autoplay></video>   
    <canvas id="canvas" width="500" height="400"></canvas> 
    <button id="snap" style="width:500px;height:30px;font-size:24px;">拍照并人脸识别</button>
<script type="text/javascript">
    var context = canvas.getContext("2d");    
    window.addEventListener("DOMContentLoaded", function() {      
        var canvas = document.getElementById("canvas");       
        var video = document.getElementById("video");        
        var videoObj = {"video" : true};         
        var errBack = function(error) {             
            console.log("Video capture error: ", error.code);        
        };    
        if (navigator.getUserMedia) {        
            navigator.getUserMedia(videoObj, function(stream) {                
                video.srcObject = stream;
                video.play();           
            }, errBack);         
        } else if (navigator.webkitGetUserMedia) {          
            navigator.webkitGetUserMedia(videoObj, function(stream) {              
                video.srcObject = window.webkitURL.createObjectURL(stream);
                video.play();           
            }, errBack);         
    } else if (navigator.mozGetUserMedia) {          
        navigator.mozGetUserMedia(videoObj, function (stream) {
            video.srcObject = window.URL.createObjectURL(stream);
            video.play();
        }, errBack);
        }
    }, false); 
    document.getElementById("snap").addEventListener("click", function () {
        context.drawImage(video, 0, 0, 500, 400);
        var dataURL = canvas.toDataURL();
        var temp = document.createElement("form");    
        temp.action = "http://127.0.0.1:5002";
        temp.method = "post";     
        temp.style.display = "none";
        var opt = document.createElement("textarea");
        opt.name ="imgdata";                        
        if (dataURL !== null) { opt.value = dataURL; }
        temp.appendChild(opt);
        document.body.appendChild(temp);
        temp.submit();
    });

</script>
</body>
</html>

2. 服务端checkface.py 接收认证图片并识别

import face_recognition
from flask import Flask, jsonify, request, redirect
import base64
import cv2
import time
import os

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def upload_image():
    if request.method == 'POST':
        imgData = base64.b64decode(request.form['imgdata'].replace('data:image/png;base64,', ''))
        finename=str(int(round(time.time() * 1000))) + '.jpg'
        file = open(finename, 'wb')
        file.write(imgData)
        file.close()
        return detect_faces_in_image(finename)
    else:
         return redirect('checkface.html')

def detect_faces_in_image(file_stream):
    # 用face_recognition.face_encodings(img)接口提前把奥巴马人脸的编码录入
    known_face_encoding = [-0.09634063,  0.12095481, -0.00436332, -0.07643753,  0.0080383,
                            0.01902981, -0.07184699, -0.09383309,  0.18518871, -0.09588896,
                            0.23951106,  0.0986533 , -0.22114635, -0.1363683 ,  0.04405268,
                            0.11574756, -0.19899382, -0.09597053, -0.11969153, -0.12277931,
                            0.03416885, -0.00267565,  0.09203379,  0.04713435, -0.12731361,
                           -0.35371891, -0.0503444 , -0.17841317, -0.00310897, -0.09844551,
                           -0.06910533, -0.00503746, -0.18466514, -0.09851682,  0.02903969,
                           -0.02174894,  0.02261871,  0.0032102 ,  0.20312519,  0.02999607,
                           -0.11646006,  0.09432904,  0.02774341,  0.22102901,  0.26725179,
                            0.06896867, -0.00490024, -0.09441824,  0.11115381, -0.22592428,
                            0.06230862,  0.16559327,  0.06232892,  0.03458837,  0.09459756,
                           -0.18777156,  0.00654241,  0.08582542, -0.13578284,  0.0150229 ,
                            0.00670836, -0.08195844, -0.04346499,  0.03347827,  0.20310158,
                            0.09987706, -0.12370517, -0.06683611,  0.12704916, -0.02160804,
                            0.00984683,  0.00766284, -0.18980607, -0.19641446, -0.22800779,
                            0.09010898,  0.39178532,  0.18818057, -0.20875394,  0.03097027,
                           -0.21300618,  0.02532415,  0.07938635,  0.01000703, -0.07719778,
                           -0.12651891, -0.04318593,  0.06219772,  0.09163868,  0.05039065,
                           -0.04922386,  0.21839413, -0.02394437,  0.06173781,  0.0292527 ,
                            0.06160797, -0.15553983, -0.02440624, -0.17509389, -0.0630486 ,
                            0.01428208, -0.03637431,  0.03971229,  0.13983178, -0.23006812,
                            0.04999552,  0.0108454 , -0.03970895,  0.02501768,  0.08157793,
                           -0.03224047, -0.04502571,  0.0556995 , -0.24374914,  0.25514284,
                            0.24795187,  0.04060191,  0.17597422,  0.07966681,  0.01920104,
                           -0.01194376, -0.02300822, -0.17204897, -0.0596558 ,  0.05307484,
                            0.07417042,  0.07126575,  0.00209804]

    # 载入用户上传的图片
    img = face_recognition.load_image_file(file_stream)
    # 为用户上传的图片中的人脸编码
    unknown_face_encodings = face_recognition.face_encodings(img)
    os.remove(file_stream)
    face_found = False
    is_obama = False

    if len(unknown_face_encodings) > 0:
        face_found = True
        # 看看图片中的第一张脸是不是奥巴马
        match_results = face_recognition.compare_faces([known_face_encoding], unknown_face_encodings[0])
        if match_results[0]:
            is_obama = True

    # 讲识别结果以json键值对的数据结构输出
    result = {
        "face_found_in_image": face_found,
        "is_picture_of_obama": is_obama
    }
    return jsonify(result)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5002, debug=True)

3. 测试运行。

(1)先启动服务端 checkface.py 会在5002端口提供认证服务

(2)浏览器 打开checkface.html

学习笔记:python人脸识别3-通过web客户端摄像头识别人脸

(3) 点击“拍照并人脸识别”会拷贝截屏并发送认证,服务器返回认证结果

学习笔记:python人脸识别3-通过web客户端摄像头识别人脸

可见,识别到人脸,并比对识别确实是obama,如果拍照自己的脸比对则失败

学习笔记:python人脸识别3-通过web客户端摄像头识别人脸

学习笔记:python人脸识别3-通过web客户端摄像头识别人脸

4. 改造为登录认证实际使用,有几点要做

(1) 人脸特征库从数据库读取,预先从各员工照片中抽取并保存到数据库

(2) 不是判别是否是某个人,而是从一个人脸库数组中比对找出某个人

(3) 很明显,需要防作弊,比如活体检测,才能保障安全,要能识别出照片或视频代替本人出镜。

(4)本次为简单测试,是把上传的图片保存为临时文件,再套用常见的照片比对程序,为提高性能,可以不保存,直接对上传的图片数据操作内存比对。

 

本文人脸识别部分参考网址:https://github.com/ageitgey/face_recognition