1. 程式人生 > >Web端人臉識別登入

Web端人臉識別登入

人臉識別技術在當下已經十分成熟,但主要在移動端應用上較為普及,而在Web端並不多見。

本文介紹在Web端人臉識別的簡單實現。

Web端人臉識別主要有三個技術思路:1.前端的人臉識別,例如使用Tensorflow.js,2.後臺人臉識別,有很多開源或者免費的SDK可以使用,3.前後端結合,即結合以上兩種方法,雖然系統複雜度提高,但對於系統的安全性,以及減輕伺服器負擔都有很大提升。

效果圖:

登入介面:

拿開面前的遮擋物後很快登入成功。

以下介紹基於後臺的Web端人臉識別。按照系統實現的簡單流程,進行分步介紹:

1.前端獲取人臉資料

通過呼叫攝像頭,將某一時刻的照片繪製在Canvas上,將Canvas轉化成jpg或png。

    var video = document.getElementById('video');
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    function getUserMediaToPhoto(constraints,success,error) {
        if(navigator.mediaDevices.getUserMedia){
            //最新標準API
            navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
        }else if (navigator.webkitGetUserMedia) {
            //webkit核心瀏覽器
            navigator.webkitGetUserMedia(constraints,success,error);
        }else if(navigator.mozGetUserMedia){
            //firefox瀏覽器
            navigator.mozGetUserMedia(constraints,success,error);
        }else if(navigator.getUserMedia){
            //舊版API
            navigator.getUserMedia(constraints,success,error);
        }
    }
    //成功回撥函式
    function success(stream){
        //相容webkit核心瀏覽器
        var CompatibleURL = window.URL || window.webkitURL;
        //將視訊流轉化為video的源
        video.src = CompatibleURL.createObjectURL(stream);
        video.play();//播放視訊
        //將視訊繪製到canvas上
        postFace()
    }
    function error(error) {
        console.log('訪問使用者媒體失敗:',error.name,error.message);
    }
    if(navigator.mediaDevices.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia){
        getUserMediaToPhoto({video:{width:480,height:320}},success,error);
    }else{
        alert('你的瀏覽器不支援訪問使用者媒體裝置');
    }

2.將人臉圖片資料傳向後臺

將圖片轉為base64格式(方便加密),通過Ajax傳向後臺,指定後臺專門的處理函式。

    function postFace() {
        setTimeout(function () {
            context.drawImage(video,0,0,480,320);
            img=canvas.toDataURL('image/jpg')
            {#獲取完整的base64編碼#}
            img=img.split(',')[1]
            //將照片以base64用ajax傳到後臺
            $.post({
                url:'/getface',
                data:{
                    message:img
                },
                success:function (callback) {
                    if(callback=='no'){
                        postFace()
                    }else {
                        window.location.href=callback
                    }
                },
                error:function (callback) {
                    postFace()
                }
            })
        },300)
    }

3.後臺接受圖片

後臺接受到base64編碼後,將編碼解密並解析,儲存成圖片。

def getface(request):
    if request.POST:
        time = datetime.datetime.now().strftime('%Y%m%d&%H%M%S')
        strs=request.POST['message']
        imgdata = base64.b64decode(strs)
        try:
            file = open(u'static/facedata/confirm/'+time+'.jpg', 'wb')
            file.write(imgdata)
            file.close()
        except:
            print('as')
        res=AFRTest.checkFace(u'static/facedata/base/niewzh.jpg',u'static/facedata/confirm/'+time+'.jpg')
        if res>=0.6:
            return HttpResponse('panel')
        else:
            return HttpResponse('no')
    else:
        return HttpResponse('no')

4.呼叫SDK進行圖片比對

假設使用者在註冊時已經上傳了作為參照的人臉資料,我們使用使用者上傳的參照人臉資料與剛剛獲得的人來拿資料進行比對,SDK獲取到兩張照片作為引數,比較後返回相似度。

def face(request):
    res = AFRTest.checkFace(u'static/facedata/base/niewzh.jpg', u'static/facedata/base/niewzh.jpg')
    return HttpResponse(res)

5.根據比對結果,返回給前端相應的資料

定義一個合適的閾值,如果相似度大於該值,判斷是該使用者,認定允許登入,返回系統介面。否則返回人臉識別失敗的資訊。

後記:

本文只介紹了簡單實現,系統安全性沒有過多考慮,比如在這個簡單系統中,前端的資料獲取流程,非註冊使用者使用註冊使用者的照片也能騙過系統,在照片資料傳輸的過程中,沒有進行base64編碼的加密,也會有資料洩露的風險。後面將會針對這些情況進行一系列的優化。

經測試,最終實現的系統可以在1s左右實現刷臉登入,識別效果也令人滿意。

專案原始碼:

密碼:psvl