1. 程式人生 > >VS2010+Opencv2.4.4+MFC實現人臉檢測與識別

VS2010+Opencv2.4.4+MFC實現人臉檢測與識別

        運用Opencv實現人臉的檢測和識別是非常方便的,也比較常用。對於人臉檢測可以用Opencv自帶的分類器實現,而人臉識別需要自建訓練分類器,以及收集人臉資料。本文重點講講人臉資料的訓練以及人臉識別的實現,識別功能的實現也結合了MFC這個基礎類庫,介面更加美觀。

1.人臉資料訓練

        在人臉模型的訓練時,可以通過CSV檔案來讀取。人臉資料為The AT&TFacedatabase,其中有40個人的人臉資料,每人10張。訓練時可加入自己的人臉圖片集,編號可記為41。關於人臉的提取可用ROI感興趣區域分割即可。CSV檔案主要儲存人臉圖片的路徑和人臉的標籤。例如本文生成的CSV檔案at.txt,如圖所示:


得到上述at.txt檔案後進行資料的訓練。訓練時用到了Opencv中提供的Facerecognixzer這個類,並且Opencv自帶了三個人臉識別的演算法:EigenfacesFisherfaces以及區域性二值模式直方圖(LBPH)。這三個演算法訓練可得到三個XML檔案,具體的訓練格式如下:

Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
model->train(images, labels);  
model->save("MyFacePCAModel.xml");
 Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer(); 
model1->train(images, labels); 
model1->save("MyFaceFisherModel.xml");
 Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
 model2->train(images, labels);
 model2->save("MyFaceLBPHModel.xml");
具體的完整程式碼可參考引用的博文,可以實現人臉資料集的訓練。
2.人臉的識別
    人臉識別的資料比較多了,網上開源的程式碼也很多,前面引用的博文裡有具體的程式碼,也可以執行實現,這裡就不貼了。人臉識別過程中主要用到haarcascade_frontalface_alt.xml這個檔案,使用該檔案主要實現人臉的檢測,框出人臉位置,再使用訓練得到的檔案(比如本文選用MyFacePCAModel.xml)來預測識別結果。測試的程式一般格式如下:
//建立用於存放人臉的向量容器  
vector<Rect> faces(0);  
cvtColor(frame, gray, CV_BGR2GRAY);
//改變影象大小,使用雙線性差值   
//變換後的影象進行直方圖均值化處理  
equalizeHist(gray, gray);  
  
cascade.detectMultiScale(gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE,Size(30, 30));
得到預測的識別結果,參考的博文中直接用modelPCA->predict(face_test),但本文測試得到的識別結果並不理想;
Mat face_test; 
int predictPCA = 0; 
if (face.rows >= 120) 
{ 
 resize(face, face_test, Size(92, 112)); }
 if (!face_test.empty()) { 
 predictPCA = modelPCA->predict(face_test); 
}
後來考慮加入predicted_confidence的閾值判斷,發現通過調整該閾值的值可以提高識別的效果。因此本文采用如下格式,並框出人臉附上名字資訊:
if (!face_test.empty())  
  {  
            //測試影象應該是灰度圖 
            modelPCA->predict(face_test,predictedLabel,predicted_confidence);
            //predictPCA = modelPCA->predict(face_test);  
  }  
        cout << predictPCA << endl;  
        if (predictedLabel == 0)//predictPCA == 40  
  {  
            string name = "HuFuping";  
            putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));  
  }
具體實現的效果圖如下(結合MFC):

關於的MFC的使用與實現本文暫不具體介紹,不是很複雜,謝謝支援~