OpenCV實(shí)現(xiàn)人臉識(shí)別
主要有以下步驟:
1、人臉檢測(cè)
2、人臉預(yù)處理
3、從收集的人臉訓(xùn)練機(jī)器學(xué)習(xí)算法
4、人臉識(shí)別
5、收尾工作
人臉檢測(cè)算法:
基于Haar的臉部檢測(cè)器的基本思想是,對(duì)于面部正面大部分區(qū)域而言,會(huì)有眼睛所在區(qū)域應(yīng)該比前額和臉頰更暗,嘴巴應(yīng)該比臉頰更暗等情形。它通常執(zhí)行大約20個(gè)這樣的比較來(lái)決定所檢測(cè)的對(duì)象是否為人臉,實(shí)際上經(jīng)常會(huì)做上千次。
基于LBP的人臉檢測(cè)器基本思想與基于Haar的人臉檢測(cè)器類(lèi)似,但它比較的是像素亮度直方圖,例如,邊緣、角落和平坦區(qū)域的直方圖。
這兩種人臉檢測(cè)器可通過(guò)訓(xùn)練大的圖像集找到人臉,這些圖像集在opencv中存在XML文件中以便后續(xù)使用。
這些級(jí)聯(lián)分類(lèi)檢測(cè)器通常至少需使用1000個(gè)獨(dú)特的人臉圖像和10000個(gè)非人臉圖像作為訓(xùn)練,訓(xùn)練時(shí)間一般LBP要幾個(gè)小時(shí),
Haar要一個(gè)星期。
項(xiàng)目中的關(guān)鍵代碼如下:
initDetectors faceCascade.load(faceCascadeFilename); eyeCascade1.load(eyeCascadeFilename1); eyeCascade2.load(eyeCascadeFilename2); initWebcam videoCapture.open(cameraNumber); cvtColor(img, gray, CV_BGR2GRAY); //有需要?jiǎng)t縮小圖片使檢測(cè)運(yùn)行更快,之后要恢復(fù)原來(lái)大小 resize(gray, inputImg, Size(scaledWidth, scaledHeight)); equalizeHist(inputImg, equalizedImg); cascade.detectMultiScale(equalizedImg......);
人臉預(yù)處理:
實(shí)際中通常訓(xùn)練(采集圖像)和測(cè)試(來(lái)自攝像機(jī)圖像)的圖像會(huì)有很大不同,受(如光照、人臉?lè)轿?、表情等)?/p>
結(jié)果會(huì)很差,因此用于訓(xùn)練的數(shù)據(jù)集很重要。
人臉預(yù)處理目的是減少這類(lèi)問(wèn)題,有助于提高整個(gè)人臉識(shí)別系統(tǒng)的可靠性。
人臉預(yù)處理的最簡(jiǎn)單形式就是使用equalizeHist()函數(shù)做直方圖均衡,這與人臉檢測(cè)那步一樣。
實(shí)際中,為了讓檢測(cè)算法更可靠,會(huì)使用面部特征檢測(cè)(如,檢測(cè)眼睛、鼻子、嘴巴和眉毛),本項(xiàng)目只使用眼睛檢測(cè)。
使用OpenCV自帶的訓(xùn)練好的眼部探測(cè)器。如,正面人臉檢測(cè)完畢后,得到一個(gè)人臉,在使用眼睛檢測(cè)器提取人臉的左眼區(qū)域和右眼區(qū)域,并對(duì)每個(gè)眼部區(qū)域進(jìn)行直方圖均衡。
這步涉及的操作有以下內(nèi)容:
1、幾何變換和裁剪
人臉對(duì)齊很重要,旋轉(zhuǎn)人臉使眼睛保持水平,縮放人臉使眼睛之間距離始終相同,平移人臉使眼睛總是在所需高度上水平居中,
裁剪人臉外圍(如圖像背景、頭發(fā)、額頭、耳朵和下巴)。
2、對(duì)人臉左側(cè)和右側(cè)分別用直方圖均衡
3、平滑
用雙邊濾波器來(lái)減少圖像噪聲
4、橢圓掩碼
將剩余頭發(fā)和人臉圖像背景去掉
項(xiàng)目中的關(guān)鍵代碼如下:
detectBothEyes(const Mat &face, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2, Point &leftEye, Point &rightEye, Rect *searchedLeftEye, Rect *searchedRightEye); topLeftOfFace = face(Rect(leftX, topY, widthX, heightY)); //在左臉區(qū)域內(nèi)檢測(cè)左眼 detectLargestObject(topLeftOfFace, eyeCascade1, leftEyeRect, topLeftOfFace.cols); //右眼類(lèi)似,這樣眼睛中心點(diǎn)就得到了 leftEye = Point(leftEyeRect.x + leftEyeRect.width/2, leftEyeRect.y + leftEyeRect.height/2); //再得到兩眼的中點(diǎn),然后計(jì)算兩眼之間的角度 Point2f eyesCenter = Point2f( (leftEye.x + rightEye.x) * 0.5f, (leftEye.y + rightEye.y) * 0.5f ); //仿射扭曲(Affine Warping)需要一個(gè)仿射矩陣 rot_mat = getRotationMatrix2D(eyesCenter, angle, scale); //現(xiàn)在可變換人臉來(lái)得到檢測(cè)到的雙眼出現(xiàn)在人臉的所需位置 warpAffine(gray, warped, rot_mat, warped.size()); //先對(duì)人臉左側(cè)和右側(cè)分開(kāi)進(jìn)行直方圖均衡 equalizeHist(leftSide, leftSide); equalizeHist(rightSide, rightSide); //再合并,這里合并時(shí)左側(cè)1/4和右側(cè)1/4直接取像素值,中間的2/4區(qū)域像素值通過(guò)一定計(jì)算進(jìn)行處理。 //雙邊濾波 bilateralFilter(warped, filtered, 0, 20.0, 2.0); //采用橢圓掩碼來(lái)刪除一些區(qū)域 filtered.copyTo(dstImg, mask);
收集并訓(xùn)練人臉:
一個(gè)好的數(shù)據(jù)集應(yīng)包含人臉變換的各種情形,這些變化可能出現(xiàn)在訓(xùn)練集中。如只測(cè)試正面人臉,則只需訓(xùn)練圖像有完全正面人臉即可。
因此一個(gè)好的訓(xùn)練集應(yīng)包含很多實(shí)際情形。
本項(xiàng)目收集的圖像之間至少有一秒的間隔,使用基于L2范數(shù)的相對(duì)錯(cuò)誤評(píng)價(jià)標(biāo)準(zhǔn)來(lái)比較兩幅圖像素之間的相似性。
errorL2 = norm(A, B, CV_L2); similarity = errorL2 / (double)(A.rows * A.cols);
再與收集新人臉的閾值相比來(lái)決定是否收集這次圖像。
可用很多技巧來(lái)獲取更多的訓(xùn)練數(shù)據(jù),如,使用鏡像人臉、加入隨機(jī)噪聲、改變?nèi)四槇D像的一些像素、旋轉(zhuǎn)等。
//翻轉(zhuǎn) flip(preprocessedFace, mirroredFace, 1);
對(duì)每個(gè)人收集到足夠多的人臉圖像后,接下來(lái)必須選擇適合人臉識(shí)別的機(jī)器學(xué)習(xí)算法,通過(guò)它來(lái)學(xué)習(xí)收集的數(shù)據(jù),從而訓(xùn)練出一個(gè)人臉識(shí)別系統(tǒng)。
人臉識(shí)別算法:
1、特征臉,也稱(chēng)PCA(主成分分析)
2、Fisher臉,也稱(chēng)LDA(線(xiàn)性判別分析)
3、局部二值模式直方圖(Local Binary Pattern Histograms,LBPH)
其他人臉識(shí)別算法:www.face-rec.org/algorithms/
OpenCV提供了CV::Algorithm類(lèi),該類(lèi)有幾種不同的算法,用其中一種算法就可以完成簡(jiǎn)單而通用的人臉識(shí)別。
OpenCV的contrib模板中有一個(gè)FaceRecognizer類(lèi),它實(shí)現(xiàn)以上這些人臉識(shí)別算法。
initModule_contrib(); model = Algorithm::create<FaceRecognizer>(facerecAlgorithm); model->train(preprocessedFaces, faceLabels);
這一代碼將執(zhí)行所選人臉識(shí)別的整個(gè)訓(xùn)練算法。
人臉識(shí)別:
1、人臉識(shí)別:通過(guò)人臉來(lái)識(shí)別這個(gè)人
可以簡(jiǎn)單調(diào)用FaceRecognizer::predict()函數(shù)來(lái)識(shí)別照片中的人,
int identity = model->predict(preprocessedFace);
它帶來(lái)的問(wèn)題是它總能預(yù)測(cè)給定的人(即使輸入圖像不屬于訓(xùn)練集中的人)。
解決此問(wèn)題的辦法是制定置信度標(biāo)準(zhǔn),置信度過(guò)低則可判讀是一個(gè)不認(rèn)識(shí)的人。
2、人臉驗(yàn)證:驗(yàn)證圖像中是否有想找的人
為了驗(yàn)證是否可靠,或者說(shuō)系統(tǒng)是否能對(duì)一個(gè)不認(rèn)識(shí)的人進(jìn)行正確識(shí)別,這需要進(jìn)行人臉驗(yàn)證。
這里計(jì)算置信度的方法是:
使用特征向量和特征值重構(gòu)人臉圖,然后將輸入的圖像與重構(gòu)圖進(jìn)行比較。如果一個(gè)人在訓(xùn)練集中有多張人臉圖,用特征向量和特征
值重構(gòu)后應(yīng)該有非常好的效果,如果沒(méi)有則差別很大,表明它可能是一個(gè)未知的人臉。
subspaceProject()函數(shù)將人臉圖像映射到特征空間,再用subspaceReconstruct()函數(shù)從特征空間重構(gòu)圖像。
收尾:交互式GUI
利用OpenCV函數(shù)很容易繪制一些組件,鼠標(biāo)點(diǎn)擊等。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
Python爬蟲(chóng)之Selenium設(shè)置元素等待的方法
這篇文章主要介紹了Python爬蟲(chóng)之Selenium設(shè)置元素等待的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12python簡(jiǎn)單驗(yàn)證碼識(shí)別的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于python簡(jiǎn)單驗(yàn)證碼識(shí)別的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05總結(jié)Python函數(shù)參數(shù)的六種類(lèi)型
這篇文章主要總結(jié)了Python函數(shù)參數(shù)的六種類(lèi)型,傳遞參數(shù)實(shí)現(xiàn)不同場(chǎng)景的靈活使用,下面總結(jié)的六種函數(shù)參數(shù)類(lèi)型,需要的小伙伴可以參考一下2022-03-03Python基于Serializer實(shí)現(xiàn)字段驗(yàn)證及序列化
這篇文章主要介紹了Python基于Serializer實(shí)現(xiàn)字段驗(yàn)證及序列化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11pycharm 實(shí)現(xiàn)調(diào)試窗口恢復(fù)
這篇文章主要介紹了pycharm 實(shí)現(xiàn)調(diào)試窗口恢復(fù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02python MNIST手寫(xiě)識(shí)別數(shù)據(jù)調(diào)用API的方法
這篇文章主要介紹了python MNIST手寫(xiě)識(shí)別數(shù)據(jù)調(diào)用API的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08python簡(jiǎn)單實(shí)現(xiàn)基于SSL的IRC bot實(shí)例
這篇文章主要介紹了python簡(jiǎn)單實(shí)現(xiàn)基于SSL的IRC bot,實(shí)例分析了IRC機(jī)器人的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-06-06