首頁 >後端開發 >Python教學 >python中OpenCV實現人臉辨識的實例詳解

python中OpenCV實現人臉辨識的實例詳解

Y2J
Y2J原創
2017-04-27 11:27:244922瀏覽

本文主要介紹了python使用opencv實現人臉辨識的相關資料。具有很好的參考價值。下面跟著小編一起來看下吧

主要有以下步驟:

#1、人臉偵測

2、人臉預處理

3、從收集的人臉訓練機器學習演算法

#4、人臉辨識

#5、收尾工作

人臉偵測演算法:

基於Haar的臉部偵測器的基本概念是,對於臉部正面大部分區域而言,會有眼睛所在區域應該比前額和臉頰更暗,嘴巴應該比臉頰更暗等情形。它通常執行大約20個這樣的比較來決定所偵測的物件是否為人臉,實際上經常會做上千次。

基於LBP的人臉偵測器基本概念與基於Haar的人臉偵測器類似,但它比較的是像素亮度直方圖,例如,邊緣、角落和平坦區域的直方圖。

這兩種人臉偵測器可透過訓練大的影像集找到人臉,這些影像集在opencv中存在XML檔案中以便後續使用。 這些級聯分類檢測器通常至少需要使用1000個獨特的人臉圖像和10000個非人臉圖像作為訓練,訓練時間一般LBP要幾個小時,

Haar要一個星期。

專案中的關鍵程式碼如下:

initDetectors
faceCascade.load(faceCascadeFilename);
eyeCascade1.load(eyeCascadeFilename1);
eyeCascade2.load(eyeCascadeFilename2);

initWebcam
videoCapture.open(cameraNumber);

cvtColor(img, gray, CV_BGR2GRAY);
//有需要则缩小图片使检测运行更快,之后要恢复原来大小
resize(gray, inputImg, Size(scaledWidth, scaledHeight));
equalizeHist(inputImg, equalizedImg);
cascade.detectMultiScale(equalizedImg......);

人臉預處理:

實際上通常訓練(擷取影像)和測試(來自攝影機影像)的影像會有很大不同,受(如光線、人臉方位、表情等),

結果會很差,因此用於訓練的資料集很重要。

人臉預處理目的是減少這類問題,有助於提高整個人臉辨識系統的可靠性。

人臉預處理的最簡單形式就是使用equalizeHist()函數做直方圖均衡,這與人臉偵測那步一樣。 實際中,為了讓偵測演算法更可靠,會使用臉部特徵偵測(如,偵測眼睛、鼻子、嘴巴和眉毛),本項目只使用眼睛偵測。 使用OpenCV自帶的訓練好的眼部偵測器。如,正面人臉偵測完畢後,得到一個人臉,在使用眼睛偵測器擷取人臉的左眼區域和右眼區域,並對每個眼部區域進行直方圖均衡。

這一步涉及的操作有以下內容:

1、幾何變換與裁切人臉對準很重要,旋轉人臉使眼睛保持水平,縮放人臉使眼睛之間距離始終相同,平移人臉使眼睛總是在所需高度上水平居中,

裁剪人臉外圍(如圖像背景、頭髮、額頭、耳朵和下巴)。 2、對人臉左邊和右邊分別用直方圖均衡

3、平滑

用雙邊濾波器來減少影像雜訊

#4、橢圓遮罩

將剩餘頭髮和人臉圖像背景去掉

專案中的關鍵程式碼如下:

detectBothEyes(const Mat &face, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2,
Point &leftEye, Point &rightEye, Rect *searchedLeftEye, Rect *searchedRightEye);
topLeftOfFace = face(Rect(leftX, topY, widthX, heightY));
//在左脸区域内检测左眼
detectLargestObject(topLeftOfFace, eyeCascade1, leftEyeRect, topLeftOfFace.cols);
//右眼类似,这样眼睛中心点就得到了
leftEye = Point(leftEyeRect.x + leftEyeRect.width/2, leftEyeRect.y + leftEyeRect.height/2);
//再得到两眼的中点,然后计算两眼之间的角度
Point2f eyesCenter = Point2f( (leftEye.x + rightEye.x) * 0.5f, (leftEye.y + rightEye.y) * 0.5f );
//仿射扭曲(Affine Warping)需要一个仿射矩阵
rot_mat = getRotationMatrix2D(eyesCenter, angle, scale);
//现在可变换人脸来得到检测到的双眼出现在人脸的所需位置
warpAffine(gray, warped, rot_mat, warped.size());

//先对人脸左侧和右侧分开进行直方图均衡
equalizeHist(leftSide, leftSide);
equalizeHist(rightSide, rightSide);
//再合并,这里合并时左侧1/4和右侧1/4直接取像素值,中间的2/4区域像素值通过一定计算进行处理。

//双边滤波
bilateralFilter(warped, filtered, 0, 20.0, 2.0);

//采用椭圆掩码来删除一些区域
filtered.copyTo(dstImg, mask);

#收集並訓練人臉:

##一個好的資料集應包含人臉變換的各種情形,這些變化可能出現在訓練集。如只測試正面人臉,只需訓練影像有完全正面人臉即可。

因此一個好的訓練集應包含許多實際情況。

本項目收集的圖像之間至少有一秒的間隔,使用基於L2範數的相對錯誤評價標準來比較兩個圖像素之間的相似性。

errorL2 = norm(A, B, CV_L2);
similarity = errorL2 / (double)(A.rows * A.cols);
再與收集新人臉的門檻相比來決定是否收集這次影像。 可用許多技巧來獲取更多的訓練數據,如,使用鏡像人臉、加入隨機雜訊、改變人臉影像的一些像素、旋轉等。
//翻转
flip(preprocessedFace, mirroredFace, 1);

對每個人收集到足夠多的人臉圖像後,接下來必須選擇適合人臉辨識的機器學習演算法,透過它來學習收集的數據,從而訓練出一個人臉辨識系統。

人臉辨識演算法:

#1、特徵臉,也稱為PCA(主成分分析)

2、Fisher臉,也稱為LDA(線性判別分析)

3、局部二值模式直方圖(Local Binary Pattern Histograms,LBPH)

其他人臉辨識演算法:www.face-rec.org/algorithms/

#OpenCV提供了CV::Algorithm類,該類有幾種不同的演算法,用其中一種演算法就可以完成簡單而通用的人臉辨識。

OpenCV的contrib模板中有一個FaceRecognizer類,它實作以上這些人臉辨識演算法。 ###
initModule_contrib();
model = Algorithm::create<FaceRecognizer>(facerecAlgorithm);

model->train(preprocessedFaces, faceLabels);
###此程式碼將執行所選人臉辨識的整個訓練演算法。 #########人臉辨識:######

1、人臉辨識:透過人臉來辨識這個人

可以簡單地呼叫FaceRecognizer::predict()函數來辨識照片中的人,

int identity = model->predict(preprocessedFace);

它帶來的問題是它總是能預測給定的人(即使輸入圖像不屬於訓練集中的人)。

解決此問題的方法是建立置信度標準,置信度過低則可判讀是一個不認識的人。

2、人臉驗證:驗證影像中是否有想找的人

為了驗證是否可靠,或系統是否能對一個不認識的人進行正確識別,這需要人臉驗證。

這裡計算置信度的方法是:

使用特徵向量和特徵值重建人臉圖,然後將輸入的影像與重構圖進行比較。如果一個人在訓練集中有多張人臉圖,用特徵向量和特徵

值重構後應該有非常好的效果,如果沒有則差別很大,表明它可能是一個未知的人臉。

subspaceProject()函數將人臉影像映射到特徵空間,再用subspaceReconstruct()函數從特徵空間重構影像。

結束:互動式GUI

利用OpenCV函數很容易繪製一些元件,滑鼠點擊等。

以上是python中OpenCV實現人臉辨識的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn