特徵臉方法主要是基於PCA降維實現。算法
詳細介紹和主要思想能夠參考數據庫
http://blog.csdn.net/u010006643/article/details/46417127app
上述博客的人臉數據庫打不開了,你們能夠去下面這個博客下載ORL人臉數據庫測試
http://blog.csdn.net/xdzzju/article/details/50445160spa
下載後,ORL人臉數據庫有40我的,每人10張照片。.net
1 #include <opencv2/opencv.hpp> 2 #include <opencv2/face.hpp> 3 4 using namespace cv; 5 using namespace cv::face; 6 using namespace std; 7 8 //對原圖歸一化 9 Mat normal(Mat src, Mat dst) { 10 if (src.channels() == 1)//若原圖單通道 11 normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1); 12 else //不然,原圖三通道 13 normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3); 14 return dst; 15 } 16 17 void main() { 18 //讀取文件,轉換爲數據流 19 string filename = string("at.txt"); 20 ifstream file(filename.c_str(), ifstream::in); 21 if (!file) 22 cout << "error" << endl; 23 24 string line, path, classlabel; 25 vector<Mat>image; 26 vector<int>labels; 27 char separator = ';'; 28 while (getline(file,line)) 29 { 30 stringstream liness(line); 31 getline(liness, path, separator); 32 getline(liness, classlabel); 33 if (!path.empty()&&!classlabel.empty()) 34 { 35 //cout << "path:" << path<< endl; 36 image.push_back(imread(path, 0)); 37 labels.push_back(atoi(classlabel.c_str())); 38 } 39 } 40 41 if (image.size() < 1 || labels.size() < 1) 42 cout << "invalid image path..." << endl; 43 44 int height = image[0].rows; 45 int width = image[0].cols; 46 //cout << "height:" << height << ",width:" << width<<endl; 47 48 //最後一我的爲測試樣本 49 Mat testSample = image[image.size() - 1]; 50 int testLabel = labels[labels.size() - 1]; 51 image.pop_back(); 52 labels.pop_back(); 53 54 //訓練 55 Ptr<BasicFaceRecognizer>model = createEigenFaceRecognizer(); 56 model->train(image, labels); 57 58 //識別 59 int predictLabel = model->predict(testSample); 60 cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl; 61 62 //得到特徵值,特徵向量,均值 平均臉 63 Mat eigenvalues = model->getEigenValues(); 64 Mat eigenvectors = model->getEigenVectors(); 65 Mat mean = model->getMean(); 66 Mat meanFace = mean.reshape(1,height); 67 Mat dst; 68 dst= normal(meanFace,dst); 69 imshow("Mean Face", dst); 70 71 //特徵臉 72 for (int i = 0; i < min(10,eigenvectors.cols); i++) 73 { 74 Mat ev = eigenvectors.col(i).clone(); 75 Mat eigenFace = ev.reshape(1, height); 76 Mat grayscale; 77 grayscale = normal(eigenFace, grayscale); 78 Mat colorface; 79 applyColorMap(grayscale, colorface, COLORMAP_BONE); 80 char* winTitle = new char[128]; 81 sprintf(winTitle, "eigenface_%d", i); 82 imshow(winTitle, colorface); 83 } 84 85 //重建人臉 86 for (int num = min(10, eigenvectors.cols); num < min(300, eigenvectors.cols); num+=15) 87 { 88 Mat evs = Mat(eigenvectors, Range::all(), Range(0, num)); 89 Mat projection = LDA::subspaceProject(evs, mean, image[0].reshape(1, 1)); 90 Mat reconstruction= LDA::subspaceReconstruct(evs, mean, projection); 91 92 Mat result = reconstruction.reshape(1, height); 93 reconstruction = normal(result, reconstruction); 94 char* winTitle = new char[128]; 95 sprintf(winTitle, "recon_face_%d", num); 96 imshow(winTitle, reconstruction); 97 } 98 99 waitKey(0); 100 }
http://blog.csdn.net/feirose/article/details/395529973d
此處只列出修改部分code
55行模型訓練 Ptr<BasicFaceRecognizer>model = createFisherFaceRecognizer(); 72行顯示特徵臉 for (int i = 0; i < min(16,eigenvectors.cols); i++) Mat ev = eigenvectors.col(i).clone(); 86行重建人臉 for (int num = 0; num < min(16, eigenvectors.cols); num++)
你們能夠參考http://blog.csdn.net/xiaomaishiwoa/article/details/46640377orm
#include <opencv2/opencv.hpp> #include <opencv2/face.hpp> using namespace cv; using namespace cv::face; using namespace std; //對原圖歸一化 Mat normal(Mat src, Mat dst) { if (src.channels() == 1)//若原圖單通道 normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1); else //不然,原圖三通道 normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3); return dst; } void main() { //讀取文件,轉換爲數據流 string filename = string("at.txt"); ifstream file(filename.c_str(), ifstream::in); if (!file) cout << "error" << endl; string line, path, classlabel; vector<Mat>image; vector<int>labels; char separator = ';'; while (getline(file,line)) { stringstream liness(line); getline(liness, path, separator); getline(liness, classlabel); if (!path.empty()&&!classlabel.empty()) { //cout << "path:" << path<< endl; image.push_back(imread(path, 0)); labels.push_back(atoi(classlabel.c_str())); } } if (image.size() < 1 || labels.size() < 1) cout << "invalid image path..." << endl; int height = image[0].rows; int width = image[0].cols; //cout << "height:" << height << ",width:" << width<<endl; //最後一我的爲測試樣本 Mat testSample = image[image.size() - 1]; int testLabel = labels[labels.size() - 1]; image.pop_back(); labels.pop_back(); //訓練 Ptr<LBPHFaceRecognizer>model = createLBPHFaceRecognizer(); model->train(image, labels); //識別 int predictLabel = model->predict(testSample); cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl; //打印參數 int radius = model->getRadius(); //中心像素點到周圍像素點的距離 int neibs = model->getNeighbors(); //周圍像素點的個數 int grad_x = model->getGridX(); //將一張圖片在x方向分紅幾塊 int grad_y = model->getGridY(); //將一張圖片在y方向分紅幾塊 double t = model->getThreshold(); //類似度閾值 cout << "radius:" << radius << endl; cout << "neibs:" << neibs << endl; cout << "grad_x:" << grad_x << endl; cout << "grad_y:" << grad_y << endl; cout << "threshold:" << t<<endl; waitKey(0); }