6
本文作者: 三川 | 2017-05-26 18:43 |
雷鋒網(wǎng)按:這是篇是利用 OpenCV 進(jìn)行人臉識(shí)別的技術(shù)講解。閱讀本文之前,這是注意事項(xiàng):
建議先讀一遍本文再跑代碼——你需要理解這些代碼是干什么的。成功跑一遍不是目的,能夠舉一反三、在新任務(wù)上找出 bug 才是。
請(qǐng)確保用的是 OpenCV v2
你需要一個(gè)網(wǎng)絡(luò)攝像頭
OpenCV 是最流行的計(jì)算機(jī)視覺(jué)庫(kù),原本用 C 和 C++ 開(kāi)發(fā),現(xiàn)在也支持 Python。
它使用機(jī)器學(xué)習(xí)算法在圖像中搜索人的面部。對(duì)于人臉這么復(fù)雜的東西,并沒(méi)有一個(gè)簡(jiǎn)單的檢測(cè)能對(duì)是否存在人臉下結(jié)論,而需要成千上萬(wàn)的特征匹配。算法把人臉識(shí)別任務(wù)分解成數(shù)千個(gè)小任務(wù),每個(gè)都不難處理。這些任務(wù)也被稱為分類器。
對(duì)于類似于人臉的對(duì)象,你或許需要不少于 6000 個(gè)分類器,每一個(gè)都需要成功匹配(當(dāng)然,有容錯(cuò)率),才能檢測(cè)出人臉。但這有一個(gè)問(wèn)題:對(duì)于人臉識(shí)別,算法從左上角開(kāi)始計(jì)算一個(gè)個(gè)數(shù)據(jù)塊,不停問(wèn)“這是張臉嗎”。每個(gè)數(shù)據(jù)塊有超過(guò) 6000 個(gè)檢測(cè),加起來(lái)的計(jì)算量會(huì)達(dá)到數(shù)百萬(wàn)級(jí)別,計(jì)算機(jī)很可能會(huì)讓你等得花兒都謝了。
OpenCV 使用 cascades 來(lái)避免這種情況。Cascade 是什么?最佳答案已經(jīng)在字典里了:一條瀑布或者連續(xù)瀑布。
好比連續(xù)瀑布,OpenCV cascade 把人臉檢測(cè)問(wèn)題分解為好幾步。對(duì)于每個(gè)數(shù)據(jù)塊,它都進(jìn)行一個(gè)粗略、快速的檢測(cè)。若通過(guò),會(huì)再進(jìn)行一個(gè)更仔細(xì)的檢測(cè),以此不斷類推。該算法有 30 到 50 個(gè)這樣的階段,或者說(shuō) cascade。只有通過(guò)全部階段,算法才會(huì)判斷檢測(cè)到人臉。這樣做的好處是:大多數(shù)圖形都會(huì)在頭幾步就產(chǎn)生否定反饋,算法因而不需要在它上面測(cè)試所有 6000 個(gè)特征,大大節(jié)省了時(shí)間。相對(duì)于“正常流程”耗費(fèi)數(shù)個(gè)小時(shí),這可以實(shí)時(shí)實(shí)現(xiàn)人臉檢測(cè)。
它的理論也許聽(tīng)起來(lái)很復(fù)雜,實(shí)際操作起來(lái)其實(shí)是很簡(jiǎn)單的。這些 cascades 只是一系列包含 OpenCV 數(shù)據(jù)的 XML 文件。你用想要的 cascade 初始化代碼,它自會(huì)替你做你想要的事。
由于人臉識(shí)別的普遍性,OpenCV 有一系列能檢測(cè)各種東西的內(nèi)置 cascade,從眼睛到手到腿都可以檢測(cè)。甚至還有針對(duì)非人體物體的 cascade。比如說(shuō),如果你經(jīng)營(yíng)一家賣香蕉的水果店,想要監(jiān)測(cè)偷香蕉的人,就有一個(gè)家伙開(kāi)發(fā)了一個(gè)針對(duì)這一場(chǎng)景的算法!
首選,你需要找到對(duì)應(yīng)你的操作系統(tǒng)的正確設(shè)置文件。
我發(fā)現(xiàn),安裝 OpenCV 是最難的一個(gè)環(huán)節(jié)。如果你遇到奇怪的、無(wú)法解釋的錯(cuò)誤,有可能是庫(kù)崩潰了、32 與 64 比特的兼容問(wèn)題等等。個(gè)人經(jīng)驗(yàn)是,只用 Linux 虛擬機(jī),從頭安裝 OpenCV 最簡(jiǎn)單。
安裝好之后,你可以開(kāi)啟一個(gè) Python 會(huì)話,敲出下面的代碼,來(lái)測(cè)試它是否能工作:
$ python
>>> import cv2
>>>
如果沒(méi)彈出任何錯(cuò)誤,你就可以到下個(gè)環(huán)節(jié)了。
源代碼可在資源庫(kù)下載。記得拿好 face_detect.py 文本、abba.png 圖片以及 haarcascade_frontalface_default.xml。下面,我把代碼分解開(kāi)來(lái)。
# Get user supplied values
imagePath = sys.argv[1]
cascPath = sys.argv[2]
將圖片和 cascade 名字作為命令行參數(shù)傳入。我們會(huì)用 Abba 圖片和 OpenCV 提供的默認(rèn) cascade 來(lái)人臉檢測(cè)。
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
現(xiàn)在,我們創(chuàng)建一個(gè) cascade,并用人臉 cascade 初始化。這把人臉 cascade 導(dǎo)入內(nèi)存,所以它隨時(shí)可以使用。記住,該 cascade 只是一個(gè)包含人臉檢測(cè)數(shù)據(jù)的 XML 文件。
# Read the image
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
讀取圖片把它轉(zhuǎn)化到灰度格式。
# Detect faces in the image
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
該函數(shù)做的就是檢測(cè)人臉,是代碼核心部分。所以,我們來(lái)過(guò)一遍選項(xiàng)。
DetectMultiScale 函數(shù)是一個(gè)檢測(cè)物體的通用函數(shù)。我們?cè)谌四?nbsp;cascade 上調(diào)用它,它檢測(cè)的就是人臉。第一個(gè)選項(xiàng)是灰度圖片。
第二個(gè)是 scaleFactor。有的人臉離鏡頭近,會(huì)比其他人臉更大。ScaleFactor 對(duì)此進(jìn)行補(bǔ)償。
檢測(cè)算法使用移動(dòng)窗口來(lái)檢測(cè)物體。在系統(tǒng)宣布檢測(cè)到人臉之前,minNeighbors 會(huì)對(duì)當(dāng)前其周圍有多少物體進(jìn)行定義。MinSize 給出每個(gè)窗口的大小。
我用的是這些領(lǐng)域的常用值?,F(xiàn)實(shí)中,你會(huì)拿不同的值試驗(yàn)窗口尺寸、擴(kuò)展因素等參數(shù),直到找出最比較合適的那一個(gè)。
當(dāng)該函數(shù)認(rèn)為它找到一張人臉時(shí),會(huì)返回一個(gè)矩形列表。下一步,我們會(huì)進(jìn)行循環(huán),直到它認(rèn)為檢測(cè)出了什么。
print "Found {0} faces!".format(len(faces))
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
該函數(shù)返回四個(gè)值:矩形的 x 和 y 坐標(biāo),以及它的高和寬。我們用這些值和內(nèi)置的 rectangle() 函數(shù),畫(huà)出矩陣。
cv2.imshow("Faces found" ,image)
cv2.waitKey(0)
最后,我們顯示該模型,等用戶摁下按鍵。
用 Abba 來(lái)檢驗(yàn)。
$ python face_detect.py abba.png haarcascade_frontalface_default.xml
沒(méi)有問(wèn)題,試試另一張照片。
那兩個(gè)東西不是臉,我們?cè)僭囈淮?。我調(diào)整了參數(shù),發(fā)現(xiàn)把 scaleFactor 調(diào)成 1.2 能去除錯(cuò)誤檢測(cè)。
發(fā)生了什么?第一張圖片由高清攝像機(jī)近距離拍攝,第二章拍攝距離相對(duì)更遠(yuǎn),而且可能是用手機(jī)拍的。這就是需要調(diào)整 scaleFactor 的原因。正如我說(shuō)的,你需要按照實(shí)際場(chǎng)景設(shè)置算法,避免假正例。
這里,雷鋒網(wǎng)提醒大家,由于這基于機(jī)器學(xué)習(xí),結(jié)果永遠(yuǎn)不會(huì) 100% 精確。大多數(shù)情況下,你會(huì)得到不錯(cuò)的結(jié)果。但算法偶爾會(huì)失誤。
最終代碼在這里。
如果你想要用網(wǎng)絡(luò)攝像頭呢?OpenCV 從攝像頭讀取每一幀,你可以通過(guò)處理每一幀進(jìn)行人臉檢測(cè)。你需要一個(gè)性能強(qiáng)大的 PC,不過(guò)我的五歲大的筆記本用著還行。
via realpython,雷鋒網(wǎng)編譯
相關(guān)文章:
手把手教你如何用 OpenCV + Python 實(shí)現(xiàn)人臉識(shí)別
老板來(lái)了:人臉識(shí)別 + 手機(jī)推送,老板來(lái)了你立刻知道!
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。