人臉識別圖像的模糊度判別算法的優(yōu)化
最近在做一個項目,需要處理網(wǎng)絡(luò)攝像頭傳過來的圖像,判斷圖像質(zhì)量,識別圖像中的人員,再做分割處理后,發(fā)給百度AIP face做人臉識別和比對.
因為,攝像頭發(fā)過來的圖像的質(zhì)量參差不齊,需要判斷圖片的清晰程度,因為是做人臉識別,尤其是要臉部清晰.所以需要判斷圖片的模糊度,來決定是否采錄圖片還是放棄.
1.強大的百度 AIP Face
百度在AI領(lǐng)域做的非常不錯,而且他的人臉識別的API也是開放的,嘗試采用類似Openface等類似的人臉識別框架后,難以達到商業(yè)級別的應(yīng)用,所以我們考慮采用百度的人臉識別系統(tǒng)作為BACKEND.
使用過程中,也覺得非常不錯,接口參數(shù)和識別率也都很不錯.
2.百度API的接口參數(shù)
我們需要做圖片的清晰度的檢查,術(shù)語就是取得圖片的blur值.blur直譯就是模糊,就是我們所說的圖片模糊度,值越小就越模糊.
在識別前,我們這邊服務(wù)器調(diào)用人員的圖片,做人臉檢測,百度AIP face會返回很多參數(shù)來判斷人臉的可信度,光照,角度,可信度及人員的年齡性別等等. 當(dāng)然這里也有blur值,表明圖片的模糊程度.
人臉檢測 返回示例:
{
"result_num": 1,
"result": [
{
"location": {
"left": 117,
"top": 131,
"width": 172,
"height": 170
},
"face_probability": 1,
"rotation_angle": 2,
"yaw": -0.34859421849251,
"pitch": 2.3033397197723,
"roll": 1.9135693311691,
"landmark": [
{
"x": 161.74819946289,
"y": 163.30244445801
},
...
],
"landmark72": [
{
"x": 115.86531066895,
"y": 170.0546875
}围苫,
...
],
"age": 29.298097610474,
"beauty": 55.128883361816,
"expression": 1,
"expression_probablity": 0.5543018579483,
"gender": "male",
"gender_probability": 0.99979132413864,
"glasses": 0,
"glasses_probability": 0.99999964237213,
"race": "yellow",
"race_probability": 0.99999976158142,
"qualities": {
"occlusion": {
"left_eye": 0,
"right_eye": 0,
"nose": 0,
"mouth": 0,
"left_cheek": 0.0064102564938366,
"right_cheek": 0.0057411273010075,
"chin": 0
},
"blur": 1.1886881756684e-10,
"illumination": 141,
"completeness": 1,
"type": {
"human": 0.99935841560364,
"cartoon": 0.00064159056637436
}
}
}
],
"log_id": 2493878179101621
}
質(zhì)量判斷
可通過人臉檢測接口耿币,基于以下字段和對應(yīng)閾值候引,進行質(zhì)量檢測的判斷邓尤,以保證人臉質(zhì)量符合后續(xù)業(yè)務(wù)操作要求权谁。
指標 字段與解釋 推薦數(shù)值界限
- 遮擋范圍 occlusion(0~1)剩檀,0為無遮擋,1是完全遮擋
- 含有多個具體子字段旺芽,表示臉部多個部位
- 通常用作判斷頭發(fā)沪猴、墨鏡、口罩等遮擋 left_eye : 0.6, #左眼被遮擋的閾值
- right_eye : 0.6, #右眼被遮擋的閾值
- nose : 0.7, #鼻子被遮擋的閾值
- mouth : 0.7, #嘴巴被遮擋的閾值
- left_check : 0.8, #左臉頰被遮擋的閾值
- right_check : 0.8, #右臉頰被遮擋的閾值
- chin_contour : 0.6, #下巴被遮擋閾值
- 模糊度范圍 Blur(0~1)采章,0是最清晰运嗜,1是最模糊 小于0.7
- 光照范圍 illumination(0~255)
- 臉部光照的灰度值,0表示光照不好
- 以及對應(yīng)客戶端SDK中悯舟,YUV的Y分量 大于40
- 姿態(tài)角度 Pitch:三維旋轉(zhuǎn)之俯仰角度[-90(上), 90(下)]
- Roll:平面內(nèi)旋轉(zhuǎn)角[-180(逆時針), 180(順時針)]
- Yaw:三維旋轉(zhuǎn)之左右旋轉(zhuǎn)角[-90(左), 90(右)] 分別小于20度
- 人臉完整度 completeness(0或1)担租,0代表完整,1代表不完整 小于0.4
- 人臉大小 人臉部分的大小
. 建議長寬像素值范圍:8080~200200 人臉部分不小于100*100像素
當(dāng)然,百度的接口參數(shù)還很多,可以到官網(wǎng)查看 百度人臉識別
3.百度的API的一個小問題
我們先看這兩張圖片:
很明顯,我們通過肉眼觀察就可以馬上判斷出來上面的照片更加模糊,下面的照片還算可以.
我們調(diào)用百度的facedetect,返回的值判斷一下那個模糊度范圍 Blur,發(fā)現(xiàn) 上一張的值要比下面的小很多,也就是百度判斷上面的照片比下面的照片要清楚很多. 這個太反直覺了,難道百度算錯了嗎?
4. 找到原因
是什么讓百度的計算有問題,難道是Blur的算法有問題嗎?
我們決定自己寫一套清晰度的算法,我們采用用 OpenCV和拉普拉斯算子來計算圖片中的模糊量,也就是拉普拉斯方差算法(Variance of the Laplacian).
只需要將圖片中的某一通道(但一般用灰度值)用下面的拉普拉斯掩模做卷積運算:
然后計算方差(即標準差的平方)抵怎。
如果某圖片方差低于預(yù)先定義的閾值奋救,那么該圖片就可以被認為是模糊的。高于閾值反惕,就不是模糊的尝艘。
這種方法湊效的原因就在于拉普拉斯算子定義本身。它被用來測量圖片的二階導(dǎo)數(shù)承璃,突出圖片中強度快速變化的區(qū)域利耍,和 Sobel 以及 Scharr 算子十分相似。并且,和以上算子一樣隘梨,拉普拉斯算子也經(jīng)常用于邊緣檢測程癌。此外,此算法基于以下假設(shè):如果圖片具有較高方差轴猎,那么它就有較廣的頻響范圍嵌莉,代表著正常,聚焦準確的圖片捻脖。但是如果圖片具有有較小方差锐峭,那么它就有較窄的頻響范圍,意味著圖片中的邊緣數(shù)量很少可婶。正如我們所知道的沿癞,圖片越模糊,其邊緣就越少矛渴。
借助opencv,代碼很簡單:
import cv2
imagePath ='./data/y1.jpg'
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print('y1 blur:',cv2.Laplacian(gray, cv2.CV_64F).var())
imagePath ='./data/y2.jpg'
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print('y2 blur:',cv2.Laplacian(gray, cv2.CV_64F).var())
y1 blur: 1663.09841446
y2 blur: 924.740511
這次真的驚得掉了下巴,竟然和百度的運算一致! 看來算法并沒問題,那么問題出在哪里呢?
思考片刻,找到答案,原來是這樣:
- 造成圖片的模糊有2個原因,一種是目標快速移動,還一種是攝像機本身抖動.
- 目前監(jiān)控攝像頭造成的迷糊原因是目標快速移動,而背景不動
- 拉普拉斯方差計算會使用拉普拉斯掩模對整張圖做卷積運算,而背景不動的部分其實很清晰,只是移動的目標部分模糊罷了,這樣整個結(jié)果值就低了.
下面,我們采用獲取人臉區(qū)域,只計算人臉區(qū)域的拉普拉斯卷積值.
圖片如下:
import cv2
imagePath ='./data/y10.jpg'
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print('y1 blur:',cv2.Laplacian(gray, cv2.CV_64F).var())
imagePath ='./data/y20.png'
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print('y2 blur:',cv2.Laplacian(gray, cv2.CV_64F).var())
y1 blur: 418.203306267
y2 blur: 1196.72339094
結(jié)果和預(yù)想的一樣完美!
這樣就知道百度API對圖像的模糊度判斷的問題了.
解決方案
我們目前,直接使用拉普拉斯卷積算子計算,只是不再最整張圖片處理,只針對臉部區(qū)域計算.這樣結(jié)果就很好.
我們建議百度能過修改AIP face中Blur的算法,及考慮相機抖動也考慮目標移動2種情況下產(chǎn)生的模糊問題,使得計算的blur值更加靠譜.