歡迎光臨
每天分享高質量文章

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


人臉特徵提取的步驟

真正的人臉識別需要很多的知識,大體上粗略的可以分為以下步驟:

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

操作過程中的註意事項

  1. 每張圖片要先上傳到 bucket 中才可以利用。

  2. API 對人臉匹配再傳回很大程度依賴於使用者的網路頻寬。

  3. 當使用者網路不好的情況下需要很久的時間才能得到傳回結果。

  4. 要經過壓縮處理,一般識別的較為準確最多可將圖片壓縮至 25 kb 左右。

我們要進行如下的步驟:

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)

(用於比對的圖片)


作者:七牛雲

源自:

https://juejin.im/post/59719caef265da6c4741cdd7

贊(0)

分享創造快樂