動手實操 | 如何用 Python 實現人臉識別,證實這個楊冪是那個楊冪?

當前,人臉識別應用於許多領域,如支付寶的用戶認證,許多的能識別人心情的 AI,也就是人的面部表情,還有能分析人的年齡等等,而這裏面有着許多的難度,在這裏我想要分享的是一個利用七牛 SDK 簡單的實現人臉識別的方法,固然七牛的 SDK 中提供了不少的拓展,在返回的 JSON 中包含着如年齡等信息,這裏就不進行分享了。這裏咱們要使用的是七牛雲平臺中由第三方數據處理提供的 API。html

如下爲官方給出的功能:python

  • 人臉 1v1 比對
  • 人臉關鍵點(106 點)
  • 人臉屬性(年齡,性別)

咱們要用的服務就是第一個:人臉 1v1 比對算法

需求分析

要作安全方面的內容,依靠人臉識別經過和庫中的臉比對後斷定類似率來驗證用戶身份。json

快速從圖片中識別出人的信息,用於尋人功能等。api

其實從安全的角度出發有不少能夠囊括的。好比智能家居中的刷臉開門,支付軟件的刷臉支付等都是例子。安全

人臉特徵提取的步驟

真正的人臉識別須要不少的知識,大致上粗略的能夠分爲如下步驟:bash

  1.人臉檢測(從圖片中找到人臉):返回人臉位置和大小的參數。
  2.人臉特徵定位:通常 69 點或者 106 個點對人臉的特徵定位,技術上有 Adaboost&haar,以及 MSRA 的 alignment。
  3.人臉特徵歸一化(幾何歸一/灰度歸一):前者對圖像進行仿射變化使得不一樣的臉能夠進行比對,後者則能使圖像展示更多的細節以及減弱光線光照的應用。
  4.特徵提取-特徵後期融合。(基於特徵近似度的多特徵融合)
  5.特徵距之間的距離來比對類似度、三氏距離。(馬氏、歐氏 、巴氏)網絡

(以上根據之前查到整理的資料得出,可能會存在認識錯誤)
能夠看出若是直接對人臉進行分析是很複雜的,而如今也有不少成熟的人臉識別庫,像是有名的 OpenCV ,OpenBR,還有國產的 Seeta Face engine 等等不少,這裏就先不介紹了,而利用開源雲平臺的 API 可使咱們的工做量更加的小。app

七牛雲 API 的優勢

應用七牛雲平臺的 API 對於使用者的能力要求較低,開發速度很快,只要輸入/返回便可,但更加適用於移動端。ide

操做過程當中的注意事項

  1. 每張圖片要先上傳到 bucket 中才能夠利用。
  2. API 對人臉匹配再返回很大程度依賴於用戶的網絡帶寬。
  3. 當用戶網絡很差的狀況下須要好久的時間才能獲得返回結果。
  4. 要通過壓縮處理,通常識別的較爲準確最多可將圖片壓縮至 25 kb 左右。

使用七牛 API 的接口準備

咱們須要用到的有 Qiniu 庫的上傳/鑑權命令,以及 requests 庫獲得處理後的圖像,以及 json 庫獲得返回給咱們的保存在 JSON 中的信息。

另外七牛的這個接口和圖片瘦身接口同樣也是要付錢的,具體的價格根據官方給的是(人臉識別對比服務 ->¥1.5/1000次 )能夠先向帳戶充入 ¥2 避免沒法使用服務。

解決問題的步驟

爲了簡化這個問題,因此本實例僅凸顯 上傳->識別 ->返回結果 的過程,對於如何經過電腦攝像頭取像,窗體制做僅提供方法和思路不進行詳細分享。

首先,咱們先分析七牛雲中這個 API 的接口 :

http://xxx.xxx.glb.clouddn.com/xxx.jpg?faceanalyze/verification/url/<urlSafeBase64URI><!-- 人臉一對一比對API-->複製代碼

咱們來分析下這個接口:
前面的xxx.xxx.glb.clouddn.com/xxx.jpg是咱們剛… 是 API 的接口,其中咱們將最後的這句 單獨拿出來講,由於這個的意思是要將咱們用於人像比對的標準人像圖片的地址通過 urlbase64 加密後的地址信息。

因此咱們要進行以下的步驟:

1)獲得咱們剛剛經過攝像頭取得的人像
2)對咱們的人像圖片進行壓縮
3)上傳咱們的人像圖片到咱們的 bucket 中
(這裏要申明一點,七牛全部支持的 API 都要求文件在華東的 Bucket 下)
4)獲得咱們上傳的圖片的連接地址
5)對連接進行 urlbase64 加密(這裏只要 import python 的 base64 庫便可)
6)請求 API
7)獲得網頁的 JSON 格式數據
8)經過 JSON 庫對數據進行分析
9)判斷人臉的類似度是否符合,輸出結果
10)刪除 Bucket 中上傳的臨時圖片

返回的 JSON 格式分析

{"status":"ok","confidence":0.73065597}複製代碼

咱們能夠看到返回的 JSON 信息很簡單, status 的意思是成功和不成功,而 confidence 則是類似度,因此咱們對返回的信息進行分析會很簡單。 status 如若成功則爲 ok,不成功則爲 invalid。

人臉類似度的判斷

上表中所用的圖片都來本身互聯網,從表數據咱們能夠大體將本人的類似度以 0.7 爲分界線。不過有趣的是,不知道爲何按楊冪進行整容的爲何類似度居然低於楊冪和范冰冰的類似度(其餘女星照的圖片爲范冰冰的人像),不一樣性別的類似度差別明顯,因此就粗略的根據表格定爲 >0.7 便可認爲是本人。

安裝所需的庫

在 python 中,我分享的這個例子總共須要引入 6 個庫

#import SDK
from qiniu import Auth,put_file,etag
import qiniu.config
import requestsimport base64
import json
from PIL import Image
import os複製代碼

requests 庫,json 庫,PIL 庫請自行安裝;
base64 庫和 OS 庫爲自帶因此無需安裝。

(因爲電腦已經安裝了較多庫,因此對於這些庫是否爲自帶也記得不太清楚,若是出現了錯誤,請你們對應本身安裝。)

程序的實現

請見下方的代碼,採集到的人臉爲 face.jpg。 (這裏用了楊冪的兩張圖片做爲示例)

#七牛雲"人臉識別"功能的python實現方法:by xlxw
#請獲得本身的Secret和Access key用於上傳圖片到空間中進行處理
#人像識別是七牛雲的一項收費項目,價格爲 ¥1.5/1000次 測試時請先存2元避免意外

#import SDK
from qiniu import Auth,put_file,etag
import qiniu.config
import requests
import base64
import json
from PIL import Image
import os

#上傳
def upload(bucket,path,filename,key,url):
    token = key.upload_token(bucket, filename, 3600)
    print('正在上傳..')
    reform,inform = put_file(token, filename, path)
    if reform != None:
        print('已經成功地將{}->>{}'.format(filename,bucket))
        print("正在處理您的圖片...")
        url=url + '/' + filename
        path=path.split('/')[-1]
    else:
        print('這裏出現了一個小錯誤.沒法上傳..')

#調用API
def apiget(urlbucket,url):
    try:
        url=urlbucket + '/001.jpg' + '?face-analyze/verification/url/' + url
        #標準對比的圖片地址,名稱爲001.jpg
        r=requests.get(url)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        print("網絡發生故障,請重試..")

#base64 Encode
def base64encode(url):
    try:
        print("正在加密連接..")
        enurl=base64.urlsafe_b64encode(bytes(url, "utf-8"))
        print("加密完成")
        enurl=str(enurl)
        enurl=enurl.split("'")[1]
        return enurl
    except:
        print("這裏出現了一個問題,請重試..")

#PIL 圖片壓縮
def pilresize(per,path):
    im=Image.open(path)
    imsize=im.size
    sizex=int(imsize[0]*per)
    sizey=int(imsize[1]*per)
    im=im.resize((sizex,sizey))
    im.save('trans.jpg','JPEG')
    print('圖片壓縮完成,輸出成功')
    print('{}->>({},{})'.format(imsize,sizex,sizey))

def pilwork(path):
    try:
        size=os.path.getsize(path)
        size = float(size)
        kb=size/1024
        per=10/kb
        pilresize(per,path)
    except:
        print("請檢查您的地址是否輸入錯誤")


#JSON分析
def jsonanal(jtext):
    print("正在分析,請稍後..")
    rj=json.loads(jtext)
    stat=rj['status']
    confi=rj['confidence']
    return stat + ',' +str(confi)

#主體
def main():
    #填寫你的 AK 和 SK
    accesskey = input('請輸入您在七牛雲的AccessKey:')
    secretkey = input('請輸入您在七牛雲的SecretKey:')

    #鑑定身份
    keyq=Auth(accesskey,secretkey)

    #所要操做的空間
    bucketname =input("請輸入要操做的空間(公開)名字:")

    #所要操做空間的外鏈地址
    urlbucket = input("請輸入空間所綁定的域名或者默認外鏈地址:")

    #斷定操做類型
    while 1:
        order=input('請輸入你須要進行的操做:')
        mode=order.split(' ')[0]
        if mode == '識別':
            path=order.split(' ')[1]
            fname=path.split('/')[-1:][0]
            unrl=urlbucket+'/trans.jpg'
            print('正在壓縮圖片.請稍後..')
            #調用函數
            pilwork(path)  #壓縮圖片
            print("正在上傳token,請稍後..")
            upload(bucketname,'./trans.jpg','trans.jpg',keyq,urlbucket) #上傳文件
            enurl=base64encode(unrl)   #base64加密
            jtext=apiget(urlbucket,enurl) #調用七牛api並獲得返回的json數據
            result=jsonanal(jtext)  #分析返回的json,獲得最終類似度
            if result.split(',')[0] == 'invalid':
                print('識別發生了錯誤')
            else:
                if eval(result.split(',')[1]) >= 0.7:
                    print("識別成功,鑑定爲本人,類似度爲{:.1f}".format(eval(result.split(',')[1])*100))
                else:
                    print("識別成功,鑑定不是本人,類似度太低")
        if mode == '退出':
            print("歡迎您的使用..")
            break

#終端提示顯示
print("+----------------------------------------+")
print("| 歡迎使用七牛的人臉識別功能 |")
print("+----------------------------------------+")
print("|本程序須知: |")
print("|1.本程序測試圖片爲楊冪的人像,見face.jpg |")
print("|2.您須要提供服務的Accesskey,Secretkey |")
print("|3.您須要提供 bucket名字和bucket外鏈地址 |")
print("+----------------------------------------+")
print("|使用方法: |")
print("|1.識別輸入格式: 識別 圖片位置(包括後綴)|")
print("|2.退出輸入格式: 退出 |")
print("+----------------------------------------+")
main()複製代碼

程序運行的截圖:

用到的楊冪的兩張照片爲:
(均來自百度圖片)

(用於比對的標準人像圖片)
(已用 PIL 壓縮 x0.3,y0.3)

(用於比對的圖片)

總結和拓展

總結

和你們分享七牛的 API 差很少結束了(說不定之後有更好玩的 API 也會拿來分享經驗)。七牛還有許多優秀方便的 API 能夠方便咱們的使用.在這期間也學習到了不少的知識,好比許多庫的熟悉掌握,像是 requests 庫、bs4 庫、 json 庫固然還有主角 Qiniu 庫。

拓展

能夠用 python 的 QT 庫開發圖形界面,而 VideoCapture 庫可用來調用電腦的攝像頭進行拍照,而後通過本文的方法就能實現簡單的人像識別了(你須要上傳標準圖片到 Qiniu 的 bucket 裏)。

可另外再加入一些標準圖片,如低光,不戴眼鏡等等的圖片,而後設計一個評判算法來適應各類各樣的狀況.本文就再也不進行拓展,有興趣的朋友能夠試試。


推薦閱讀


報名方式:有更多有趣的做品分享給你們?掃描上方 二維碼和美女隊長接頭,便可成爲【動手實操】系列玩家。
相關文章
相關標籤/搜索