Face++提供API和SDK試用,註冊後有一星期的使用時長,註冊不須要身份證照片,手機註冊便可,SDK付費,不過用法好像跟API差很少python
參考博客:json
廖雪峯的官方網站:內置模塊:urllib 第三方模塊:requestsapi
Face++ Detect API: 文檔(重要) API演示app
返回值是Json文件,照着文檔解字典便可獲得數據,rectangle和landmark使用使用PIL包的函數進行繪製函數
# -*- coding: utf-8 -*- import urllib.request import urllib.error import matplotlib.pyplot as plt import time import json from skimage import io import numpy as np from PIL import Image, ImageDraw http_url = 'https://api-cn.faceplusplus.com/facepp/v3/detect' key = "740HGdE-kYbuHiv5K7bz0Sy4v2oUcT1m" secret = "t8ctrIbKdhUpmkR_sp5fAxEETTbDrP9N" filepath = r"C:\Users\xiexj\Desktop\test.jpg" boundary = '----------%s' % hex(int(time.time() * 1000)) data = [] data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="%s"\r\n' % 'api_key') data.append(key) data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="%s"\r\n' % 'api_secret') data.append(secret) data.append('--%s' % boundary) fr = open(filepath, 'rb') data.append('Content-Disposition: form-data; name="%s"; filename=" "' % 'image_file') data.append('Content-Type: %s\r\n' % 'application/octet-stream') data.append(fr.read()) fr.close() data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="%s"\r\n' % 'return_landmark') data.append('2') data.append('--%s' % boundary) data.append('Content-Disposition: form-data; name="%s"\r\n' % 'return_attributes') data.append( "gender,age,smiling,headpose,facequality,blur,eyestatus,emotion,ethnicity,beauty,mouthstatus,eyegaze,skinstatus") data.append('--%s--\r\n' % boundary) for i, d in enumerate(data): if isinstance(d, str): data[i] = d.encode('utf-8') # change to byte type http_body = b'\r\n'.join(data) # build http request req = urllib.request.Request(url=http_url, data=http_body) # header req.add_header('Content-Type', 'multipart/form-data; boundary=%s' % boundary) try: # post data to server resp = urllib.request.urlopen(req, timeout=5) # get response qrcont = resp.read() # if you want to load as json, you should decode first, # for example: json.loads(qrcont.decode('utf-8')) # print(qrcont.decode('utf-8')) dic = json.loads(qrcont.decode('utf-8')) # print(dic) print(type(dic)) faces_data = dic['faces'] faces_data = faces_data[0] print(faces_data.get('face_token')) print(faces_data.get('face_rectangle')) dictFace = faces_data.get('face_rectangle') left = dictFace['left'] top = dictFace['top'] height = dictFace['height'] width = dictFace['width'] # landmark dictLandmark = faces_data.get('landmark') img = Image.open(filepath) print(type(img)) img1 = np.array(img) draw = ImageDraw.Draw(img) draw.line([(left, top), (left + width, top), (left + width, top + height), (left, top + width), (left, top)], 'red') new_img = img1[top:(top + height), left:(left + width)] io.imsave(r"C:\Users\xiexj\Desktop\res.jpg", new_img) for i in dictLandmark: top = dictLandmark[i]['y'] left = dictLandmark[i]['x'] draw.line([(left, top), (left + 1, top), (left + 1, top + 1), (left, top + 1), (left, top)], 'blue') img.show() # attributes dictAttributes = faces_data.get('attributes') print("gender: %s" % dictAttributes.get("gender").get("value")) print("age: %s" % dictAttributes.get("age").get("value")) print("glass: %s" % dictAttributes.get("glass").get("value")) print("ethnicity: %s" % dictAttributes.get("ethnicity").get("value")) print("beauty_male: %s" % dictAttributes["beauty"]["male_score"]) print("beauty_female: %s" % dictAttributes["beauty"]["female_score"]) except urllib.error.HTTPError as e: print(e.read().decode('utf-8'))
挑一段核心代碼(加上了輸出):post
for i, d in enumerate(data): if isinstance(d, str): data[i] = d.encode('utf-8') # change to byte type http_body = b'\r\n'.join(data) for i in range(len(data)): print(data[i]) print("??????????????????????????????????????????????????") print(type(http_body)) print(http_body) # build http request req = urllib.request.Request(url=http_url, data=http_body) # header req.add_header('Content-Type', 'multipart/form-data; boundary=%s' % boundary)
輸出:網站
不清楚爲何要加上這些boundary,但註釋掉報錯:{"error_message":"MISSING_ARGUMENTS: api_secret"}ui
能夠看到要進行url請求的 http_body 爲ascii編碼格式編碼
返回值(106個關鍵點):url
D:\Anaconda\python.exe D:/code/face++/test.py <class 'dict'> 354026ba716d35a2f3acc8ccd74c512b {'width': 77, 'top': 48, 'left': 149, 'height': 77} <class 'PIL.JpegImagePlugin.JpegImageFile'> gender: Male age: 58 glass: None ethnicity: WHITE beauty_male: 29.189 beauty_female: 41.781 Process finished with exit code 0
本亮大叔的實際年齡55,預測值58,人種預測是白色,顏值是29分......仍是有點扯
D:\Anaconda\python.exe D:/code/face++/test.py <class 'dict'> 6445cf79037f4b82a962badf796fee21 {'width': 256, 'top': 335, 'left': 202, 'height': 256} <class 'PIL.JpegImagePlugin.JpegImageFile'> gender: Male age: 25 glass: Dark ethnicity: INDIA beauty_male: 87.41 beauty_female: 88.369 Process finished with exit code 0
黃景瑜實際年齡27,預測年齡25,戴眼鏡,印度人種?顏值87分......
曠世的API還提供了不少有意思的檢測,我沒有都提取出來
我這裏使用的是Detect API,這個API基本包括了人臉識別的檢測屬性,比較全,另外還有人臉識別,證件識別,圖像識別