多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > OpenCV+Qt:基于PCA主成分分析的人臉識別例程

OpenCV+Qt:基于PCA主成分分析的人臉識別例程

來源:程序員人生   發布時間:2015-07-03 08:43:26 閱讀次數:3655次

在模式辨認領域中,PCA是1種經常使用的數據集降維手段,在此基礎上,保存數據集中對方差貢獻最大的特點從而進行模式分類。OpenCV中提供PCA的類,因此可以方便地使用PCA來進行人臉辨認研究。在學習了網上的相干實現和代碼,在以下開發平臺跑通了代碼:win8.1+OpenCV2.4.9+Qt5.3.2。

1、基本步驟

關于PCA的1些理論,可參照:http://blog.csdn.net/liyuefeilong/article/details/45126255 以下是實現PCA的基本思路:

1.把原始數據中每一個樣本用1個向量表示,然后把所有樣本組合起來構成1個矩陣。這里為了不樣本單位對后續處理的影響,樣本集需要標準化。

2.求樣本的散布矩陣。事實上,散布矩陣是樣本協方差矩陣的(n⑴)倍,而協方差矩陣則表示不同隨機變量之間的相互關系,在圖象中則等價為求兩個像素之間的關系。這里散布矩陣是實對稱矩陣。

3.對第2步中得到的散布矩陣求相應的特點值和特點向量。

4.所謂主成份分析,即需要得到具有最大特點值的特點向量,所以我們需要將特點向量依照特點值由大到小排序并構成1個映照矩陣,并根據指定的PCA保存的特點個數取出映照矩陣的前n行或前n列作為終究的映照矩陣。

5.用第4步的映照矩陣對訓練樣本數據進行映照,到達數據降維的目的。假定原始的圖象數據是m*n的矩陣,只包括主成份的特點向量構成1個n*p的矩陣,其中每列都是1個特點向量。將兩個矩陣相乘,便可取得降維以后的圖象矩陣m*p,這個矩陣遠小于原始的圖象數據。

6.同步驟5,讀取所有測試集圖象,并對其進行降維操作。如果測試集有M幅圖象,則降維后的矩陣為M*p。

7.最后,對測試集進行模式辨認。

在本次實驗實現的進程中,需要用到opencv的這些函數,下面簡單介紹下這些函數。

2、OpenCV中需要用到的幾個函數

PCA::PCA(InputArray data, // 輸入1個矩陣 InputArray mean, // 輸出1個句子 int flags, // 輸入矩陣數據的存儲方式,有以下兩種參數設定 // CV_PCA_DATA_AS_ROW:代表輸入矩陣的每行表示1個樣本 // CV_PCA_DATA_AS_COL:代表輸入矩陣的每列表示1個樣本 int maxComponents=0) // 計算PCA時保存的最大主成份的個數
// 該函數將輸入數據投影到PCA主成份空間中去 // 返回每個樣本主成份特點組成的矩陣 cv::Mat PCA::project(InputArray vec) const
// 調用backProject函數前1般已調用過project()函數 // 其作用可理解為project()函數的逆運算 // 函數的作用就是用vec來重構原始數據集(原理有待進1步了解) cv::Mat PCA::backProject(InputArray vec) const

另外PCA類中還有幾個重要的成員變量:

mean // 原始數據的均值 eigenvectors // 散布矩陣(協方差矩陣)的特點值 eigenvalues // 散布矩陣(協方差矩陣)的特點向量

3、相干代碼

根據網上提供的代碼,修改成可以在開發平臺上使用的版本:

#ifndef PCAFACE_H #define PCAFACE_H #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; #include <QDialog> namespace Ui { class PCAFace; } class PCAFace : public QDialog { Q_OBJECT public: explicit PCAFace(QWidget *parent = 0); ~PCAFace(); Mat normalize(const Mat& src); protected: void changeEvent(QEvent *e); private slots: void on_startButton_clicked(); void on_closeButton_clicked(); private: Ui::PCAFace *ui; Mat src_face1, src_face2, src_face3; Mat project_face1, project_face2, project_face3; Mat dst; Mat pca_face1, pca_face2, pca_face3; vector<Mat> src; int total; }; #endif // PCAFACE_H
#include "pcaface.h" #include "ui_pcaface.h" #include <QString> #include <iostream> #include <stdio.h> #include <QDir> #include <QDebug> using namespace std; QDir dir; QString runPath = dir.currentPath(); PCAFace::PCAFace(QWidget *parent) : QDialog(parent), ui(new Ui::PCAFace) { ui->setupUi(this); src_face1 = imread("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/images/1.pgm", 0); //下面的代碼為設置圖片顯示區域自適應圖片的大小 ui->face1Browser->setFixedHeight(src_face1.rows+1); ui->face1Browser->setFixedWidth(src_face1.cols+1); ui->face2Browser->setFixedHeight(src_face1.rows+1); ui->face2Browser->setFixedWidth(src_face1.cols+1); ui->face3Browser->setFixedHeight(src_face1.rows+1); ui->face3Browser->setFixedWidth(src_face1.cols+1); ui->face4Browser->setFixedHeight(src_face1.rows+1); ui->face4Browser->setFixedWidth(src_face1.cols+1); ui->face5Browser->setFixedHeight(src_face1.rows+1); ui->face5Browser->setFixedWidth(src_face1.cols+1); ui->face6Browser->setFixedHeight(src_face1.rows+1); ui->face6Browser->setFixedWidth(src_face1.cols+1); ui->face7Browser->setFixedHeight(src_face1.rows+1); ui->face7Browser->setFixedWidth(src_face1.cols+1); ui->face8Browser->setFixedHeight(src_face1.rows+1); ui->face8Browser->setFixedWidth(src_face1.cols+1); ui->face9Browser->setFixedHeight(src_face1.rows+1); ui->face9Browser->setFixedWidth(src_face1.cols+1); for(int i = 1; i <= 15; i++) { stringstream str; string num; str<<i;// 將整數i讀入字符串流 str>>num;// 將字符串流中的數據傳入num,這2句代碼即把數字轉換成字符 string image_name = ("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/images/" + num + ".pgm");//需要讀取的圖片全名 src.push_back(imread(image_name, 0)); } total= src[0].rows*src[0].cols; } PCAFace::~PCAFace() { delete ui; } void PCAFace::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } // 將Mat內的內容歸1化到0255,歸1化后的類型為8位無符號整型單通道 Mat PCAFace::normalize(const Mat& src) { Mat norm_src; cv::normalize(src, norm_src, 0, 255, NORM_MINMAX, CV_8UC1); return norm_src; } void PCAFace::on_startButton_clicked() { //先顯示3張原圖 ui->face1Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/images/5.pgm>"); ui->face2Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/images/7.pgm>"); ui->face3Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/images/14.pgm>"); //mat數組用來寄存讀取進來的所有圖片的數據,其中mat的每列對應1張圖片,該實現在下面的for函數中 Mat mat(total, src.size(), CV_32FC1); for(int i = 0; i < src.size(); i++) { Mat col_tmp = mat.col(i); src[i].reshape(1, total).col(0).convertTo(col_tmp, CV_32FC1, 1/255.); } int number_principal_compent = 12;//保存最大的主成份數 //構造pca數據結構 PCA pca(mat, Mat(), CV_PCA_DATA_AS_COL, number_principal_compent); //pca.eigenvectors中的每行代表輸入數據協方差矩陣1個特點向量,且是依照該協方差矩陣的特點值進行排序的 pca_face1 = normalize(pca.eigenvectors.row(0)).reshape(1, src[0].rows);//第1個主成份臉 imwrite("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/pca_face1.jpg", pca_face1);//顯示主成份特點臉1 ui->face7Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/pca_face1.jpg>"); pca_face2 = normalize(pca.eigenvectors.row(1)).reshape(1, src[0].rows);//第2個主成份臉 imwrite("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/pca_face2.jpg", pca_face2);//顯示主成份特點臉2 ui->face8Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/pca_face2.jpg>"); pca_face3 = normalize(pca.eigenvectors.row(2)).reshape(1, src[0].rows);//第3個主成份臉 imwrite("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/pca_face3.jpg", pca_face3);//顯示主成份特點臉3 ui->face9Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/pca_face3.jpg>"); //將原始數據通過PCA方向投影,即通過特點向量的前面幾個作用后的數據,因此這里的dst的尺寸變小了 dst = pca.project(mat); //通過方向投影重構原始人臉圖象 project_face1 = normalize(pca.backProject(dst).col(0)).reshape(1, src[0].rows); imwrite("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/project_face1.jpg", project_face1); ui->face4Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/project_face1.jpg>"); project_face2 = normalize(pca.backProject(dst).col(1)).reshape(1, src[0].rows); imwrite("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/project_face2.jpg", project_face2); ui->face5Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/project_face2.jpg>"); project_face3 = normalize(pca.backProject(dst).col(2)).reshape(1, src[0].rows); imwrite("C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/project_face3.jpg", project_face3); ui->face6Browser->append("<img src=C:/Users/peng__000/Desktop/PR.proj05/OpenCV4PCA/PCA_Face/result/project_face3.jpg>"); } void PCAFace::on_closeButton_clicked() { close(); }
#include <QApplication> #include "pcaface.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); PCAFace w; w.show(); return a.exec(); }

這里寫圖片描述

其中第1行的3張人臉分別為ORL人臉庫其中的3張,分別取3個不同的人。

第2行中顯示的3張人臉分別為第1行中人臉經過PCA投影函數Project后,又調用反向投影函數backProject變換回來的人臉圖象。

第3行的人臉圖為取的原始數據計算散布矩陣的特點向量的最前面3個,使用這3個向量所得到的輸出最能代表人臉特點。

最后感謝代碼原文介紹:http://www.cnblogs.com/tornadomeet/archive/2012/09/06/2673104.html

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 不卡中文一二三区 | 欧美日韩在线精品成人综合网 | 日韩久久久精品中文字幕 | 欧美亚洲国产一区二区三区 | 91porn国产在线观看 | 中文字幕在线观看免费视频 | 亚洲天堂v | 成人免费视频一区 | 中文精品视频一区二区在线观看 | 国内精神品一区区 | 久久精品大片 | 高清欧美性猛交xxxx黑人猛交 | 69精品视频| 午夜在线视频免费 | 日韩亚洲欧美一区二区三区 | 午夜影院私人 | 日韩免费一区二区三区 | 日韩欧美小说 | 欧美日韩亚洲成人 | 麻豆19禁国产青草精品 | 磁力天堂网在线资源www | 中文字幕精品一区二区精品 | 大色欧美| 亚洲丶国产丶欧美一区二区三区 | 欧洲免费无线码二区5 | 国产精品久久久久久久 | 欧美一区二区三区在线观看 | 忘忧草wyc.apk | 黄色ab| 曰本裸色私人影院噜噜噜影院 | 最近最新视频中文字幕3 | 亚洲一区二区三区久久精品 | 欧美性最猛xxxx在线观看视频 | 欧美性free xxx| 欧美亚洲免费久久久 | 国产精品一级二级三级 | 在线免费观看h | 波多野结衣国产一区二区三区 | 性色a| 香蕉超级碰碰碰97视频在线观看 | 伊人影院2019|