用2263份證件照圖片樣本測試how-old.net的人臉識別


上一年也就是這個時候微軟根據自己的人臉識別API推出了一個識別照片中人臉年齡和性別的網站——http://how-old.net,小伙伴們各種玩耍,一年后的今天突發“奇想”地想測試一下這個網站的識別情況。正好手里有3萬多份標識有身份證信息、性別及照片拍攝時間的證件照(別問我從哪兒弄的,這玩意兒你懂的)。今天就寫了個腳本來測試一下。測試識別的目標有兩個:

  • 性別
  • 年齡

提交數據獲得識別結果

尋找接口

首先,查看一下how-old.net的提交接口。

用Chrome查看一下網絡請求的情況

查看一下前三個請求的數據情況:

第一個:

第二個:

第三個:


很奇怪有沒有,第一個是一個bolb地址,第二個是圖片的base64編碼后的字符,第三個倒像是真正的請求,可查看請求中,盡然找不到對應圖片的參數。再查看一下第三個請求的響應:

嗯,一個添加轉移符號的json數據,我們想要的識別結果確實在里面。這就確定這個請求就是我們需要的請求接口,現在的問題是怎樣上傳圖片數據呢?

我們不妨從頭看一下這三個請求。第一個中的bolb地址和第二個請求中的base64數據是怎么個情況呢?在Stack Overflow上查找到了下面的信息:

簡單來說就是,在二進制數據以流式方式提交的時候,有這樣一個模式:生成一個bolb地址做本機數據訪問 -> 訪問具體的信息是是base64編碼的的文件 -> 對指定接口以流式上傳數據。也就是說前兩個請求時發生在本機的,是對本地資源的訪問,第三個請求才是真正的請求,只不過數據是前兩個“本機請求”生成的流式數據。

上傳數據獲得識別結果

這樣我們就得到了我們需要的訪問接口及數據提交方式:

  • 接口:
  • 提交方式:POST流式提交

我們可以在上面第三個請求圖中查看到請求參數及header,cookies等信息。使用requests庫能很容易做到數據流式提交,針對此接口請求代碼如下:

	#訪問主頁獲得cookie
	t = requests.get("http://how-old.net",timeout=60)
    _cookies = t.cookies
    t.close()
	
	#構建請求頭
    headers = {
        "Content-Type": "application/octet-stream",
        "Referer": "http://how-old.net/",
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
    }
	
    info = None
	#POST方式流式提交(pic_name是圖片地址)
    with open(pic_name, 'rb') as f:
        r = requests.post("http://how-old.net/Home/Analyze?isTest=False&source=&version=how-old.net",
                          data=f,
                          headers=headers,
                          cookies=_cookies,
                          timeout=10)
        info = r.content

將返回的識別數據存儲在info中,其樣式像下面這樣:

"{\"AnalyticsEvent\":\"[\\r\\n  {\\r\\n    \\\"face\\\": {\\r\\n      \\\"age\\\": 16.0,\\r\\n      \\\"gender\\\": \\\"Male\\\"\\r\\n    },\\r\\n    \\\"event_datetime\\\": \\\"2016-04-30T11:39:30.4786437Z\\\",\\r\\n    \\\"user_id\\\": \\\"ab85e356-6638-41e7-a46f-be54c1f94f97\\\",\\r\\n    \\\"session_id\\\": \\\"ba5ec8e4-65e0-481d-b034-970494680bca\\\",\\r\\n    \\\"submission_method\\\": \\\"Upload\\\",\\r\\n    \\\"user_agent\\\": \\\"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36\\\",\\r\\n    \\\"location\\\": {\\r\\n      \\\"latitude\\\": 35.71,\\r\\n      \\\"longitude\\\": 115.23\\r\\n    },\\r\\n    \\\"location_city\\\": {\\r\\n      \\\"latitude\\\": 35.7,\\r\\n      \\\"longitude\\\": 115.2\\r\\n    },\\r\\n    \\\"is_mobile_device\\\": false,\\r\\n    \\\"browser_type\\\": \\\"Chrome\\\",\\r\\n    \\\"platform\\\": \\\"Windows\\\",\\r\\n    \\\"mobile_device_model\\\": \\\"Unknown\\\"\\r\\n  }\\r\\n]\",\"Faces\":[{\"faceId\":null,\"faceRectangle\":{\"top\":29,\"left\":49,\"width\":51,\"height\":51},\"attributes\":{\"gender\":\"Male\",\"age\":16.0}}]}"

正想我們在Chrome中觀測到的返回數據一樣,這樣通過Python提交圖片並獲得識別數據就成功了。

但是這樣的數據我們很難使用,因為里面數據很多且有很多的轉義,所以先把\r``\n``\這樣的數據清洗掉,並選取其中最后面的一部分,獲得下面的結構數據:

{
    "Faces": [
        {
            "faceId": null,
            "faceRectangle": {
                "top": 29,
                "left": 49,
                "width": 51,
                "height": 51
            },
            "attributes": {
                "gender": "Male",
                "age": 16
            }
        }
    ]
}

faceId是圖片中識別出的臉的標號,faceRectangle是將臉部框前來的矩形左上坐標及寬高,attributes中是識別出的性別和年齡。由於證件照都是標准的一個人,網站基本都能識別出來,所以只考慮一張圖片對應的一個attributes。將照片對應的信息存在一個persons列表中,樣式如下:

persons = [
			{
				"num":num,
				"real_age":real_age,
				"real_gender":real_gender,
				"rec_age":rec_age,
				"rec_gender":rec_gender
			}
		]

識別結果統計

性別識別

性別識別統計很容易,直接比對一張照片對應的實際性別和識別:

toatal = len(persons)
right = 0
wrong_fm = 0
wrong_mf = 0
for person in persons:
	if person["real_gender"] == person["rec_gender"]:
		right += 1
	elif person["real_gender"] == "Female":
		wrong_fm += 1
	else:
		wrong_mf +=1

最終的結果是:

年齡識別

年齡的識別統計采用一個字典記錄,其結構是識別{某年齡差:識別為該年齡差的個數}:

age_rec = {}
for person in persons:
	tmp = person["rec_age"] - person["real_age"]
	try:
		age_rec[tmp] += 1
	except:
		pass
	finally:
		age_rec[tmp] = 1

最終的統計結果是:

結語

本實踐統計了HOW-OLD對兩千多份圖片樣本的識別結果,性別識別正確率很高,而年齡識別錯誤范圍較大,且識別結果偏大的居多。我甚至覺得,這東西可以用來檢測攝影師的拍照技術,識別結果越小,人物攝影技術越好:)(開個玩笑)。整個實踐最麻煩的地方是找接口及上傳數據的方法,最費時間的是上傳數據獲得結果這個過程(受網絡IO的限制,用家里的小破wifi,使用多線程也沒多大用,而且線程一多,就會掉線:()。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM