日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)

發布時間:2024/4/17 pytorch 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】PCA算法学习_1(OpenCV中PCA实现人脸降维) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

  PCA是大家經常用來減少數據集的維數,同時保留數據集中對方差貢獻最大的特征來達到簡化數據集的目的。本文通過使用PCA來提取人臉中的特征臉這個例子,來熟悉下在oepncv中怎樣使用PCA這個類。

  開發環境:ubuntu12.04+Qt4.8.2+QtCreator2.5.1+opencv2.4.2

?

  PCA數學理論:

  關于PCA的理論,資料很多,公式也一大把,本人功底有限,理論方面這里就不列出了。下面主要從應用的角度大概來講講具體怎么實現數據集的降維。

  • 把原始數據中每個樣本用一個向量表示,然后把所有樣本組合起來構成一個矩陣。當然了,為了避免樣本的單位的影響,樣本集需要標準化。

  • 求該矩陣的協防差矩陣(關于協方差的介紹可以參考我的博文:一些知識點的初步理解_4(協方差矩陣,ing...))。

  • 求步驟2中得到的協方差矩陣的特征值和特征向量。

  • 將求出的特征向量按照特征值的大小進行組合形成一個映射矩陣,并根據指定的PCA保留的特征個數取出映射矩陣的前n行或者前n列作為最終的映射矩陣。

  • 用步驟4的映射矩陣對原始數據進行映射,達到數據降維的目的。

  • ?

      實驗說明:

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

      Mat?Mat::reshape(int?cn, int?rows=0)?const

      該函數是改變Mat的尺寸,即保持尺寸大小=行數*列數*通道數 不變。其中第一個參數為變換后Mat的通道數,如果為0,代表變換前后通道數不變。第二個參數為變換后Mat的行數,如果為0也是代表變換前后通道數不變。但是該函數本身不復制數據(這點不是很理解,調用一個Mat的reshape,如果我們不把調用后的Mat做為返回值去用,難道此時調用前的Mat一點變化都沒有?)。

    ?

      void?Mat::convertTo(OutputArray?m, int?rtype, double?alpha=1, double?beta=0?)?const

      該函數其實是對原Mat的每一個值做一個線性變換。參數1為目的矩陣,參數2為目d矩陣的類型,參數3和4變換的系數,看完下面的公式就明白了:

      

    ?

      PCA::PCA(InputArray?data, InputArray?mean, int?flags, int?maxComponents=0)

      該構造函數的第一個參數為要進行PCA變換的輸入Mat;參數2為該Mat的均值向量;參數3為輸入矩陣數據的存儲方式,如果其值為CV_PCA_DATA_AS_ROW則說明輸入Mat的每一行代表一個樣本,同理當其值為CV_PCA_DATA_AS_COL時,代表輸入矩陣的每一列為一個樣本;最后一個參數為該PCA計算時保留的最大主成分的個數。如果是缺省值,則表示所有的成分都保留。

    ?

      Mat?PCA::project(InputArray?vec)?const

      該函數的作用是將輸入數據vec(該數據是用來提取PCA特征的原始數據)投影到PCA主成分空間中去,返回每一個樣本主成分特征組成的矩陣。因為經過PCA處理后,原始數據的維數降低了,因此原始數據集中的每一個樣本的維數都變了,由改變后的樣本集就組成了本函數的返回值。

    ?

      Mat?PCA::backProject(InputArray?vec)?const

      一般調用backProject()函數前需調用project()函數,因為backProject()函數的參數vec為經過PCA投影降維過后的矩陣。 因此backProject()函數的作用就是用vec來重構原始數據集(關于該函數的本質數學實現暫時還不是很了解)。

      另外PCA類中還有幾個成員變量,mean,eigenvectors, eigenvalues等分別對應著原始數據的均值,協方差矩陣的特征值和特征向量。

    ?

      實驗結果:

      本次實驗是用4個人人臉圖像,其中每個人分別有5張,共計20張人臉圖片。用這些圖片組成原始數據集來提取他們的PCA主特征臉。該20張圖片如下所示:

      

    ?

      當運行軟件后,單擊start按鈕,該程序的結果顯示如下:

      ?

      其中第一行的3張人臉分別為20張原圖中的3張,這里取的是3個不同人的。

      第二行中顯示的3張人臉分別為第一行中人臉經過PCA投影后,又方向投影過來的人臉圖像,仔細觀察可以看到第二行的人臉圖像整體比第一行的亮度上要亮些,且細節上也有所不同。

      第3行的人臉圖為取的原始數據協方差矩陣特征向量的最前面3個,因此這3個人臉為最具代表人臉特征的3個PCA人臉特征。

    ?

      實驗主要部分代碼即注釋(附錄有實驗工程code下載鏈接):

    pcaface.h:

    #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_OBJECTpublic: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

    ?

    pcaface.cpp:

    #include "pcaface.h" #include "ui_pcaface.h" #include <QString> #include <iostream> #include <stdio.h>using namespace std;PCAFace::PCAFace(QWidget *parent) :QDialog(parent),ui(new Ui::PCAFace) {ui->setupUi(this);src_face1 = imread("./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 ss;string num;ss<<i;//將整數i讀入字符串流ss>>num;//將字符串流中的數據傳入num,這2句代碼即把數字轉換成字符string image_name = ("./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內的內容歸一化到0~255,歸一化后的類型為但通道整型 Mat PCAFace::normalize(const Mat& src) {Mat srcnorm;cv::normalize(src, srcnorm, 0, 255, NORM_MINMAX, CV_8UC1);return srcnorm; }void PCAFace::on_startButton_clicked() {//先顯示3張原圖ui->face1Browser->append("<img src=./images/1.pgm>");ui->face2Browser->append("<img src=./images/7.pgm>");ui->face3Browser->append("<img src=./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中的每一行代表輸入數據協方差矩陣一個特征向量,且是按照該協方差矩陣的特征值進行排序的pca_face1 = normalize(pca.eigenvectors.row(0)).reshape(1, src[0].rows);//第一個主成分臉imwrite("./result/pca_face1.jpg", pca_face1);//顯示主成分特征臉1ui->face7Browser->append("<img src=./result/pca_face1.jpg>");pca_face2 = normalize(pca.eigenvectors.row(1)).reshape(1, src[0].rows);//第二個主成分臉imwrite("./result/pca_face2.jpg", pca_face2);//顯示主成分特征臉2ui->face8Browser->append("<img src=./result/pca_face2.jpg>");pca_face3 = normalize(pca.eigenvectors.row(2)).reshape(1, src[0].rows);//第三個主成分臉imwrite("./result/pca_face3.jpg", pca_face3);//顯示主成分特征臉3ui->face9Browser->append("<img src=./result/pca_face3.jpg>");//將原始數據通過PCA方向投影,即通過特征向量的前面幾個作用后的數據,因此這里的dst的尺寸變小了dst = pca.project(mat);//通過方向投影重構原始人臉圖像(其本質暫時還沒完全弄明白)project_face1 = normalize(pca.backProject(dst).col(0)).reshape(1, src[0].rows);imwrite("./result/project_face1.jpg", project_face1);ui->face4Browser->append("<img src=./result/project_face1.jpg>");project_face2 = normalize(pca.backProject(dst).col(6)).reshape(1, src[0].rows);imwrite("./result/project_face2.jpg", project_face2);ui->face5Browser->append("<img src=./result/project_face2.jpg>");project_face3 = normalize(pca.backProject(dst).col(13)).reshape(1, src[0].rows);imwrite("./result/project_face3.jpg", project_face3);ui->face6Browser->append("<img src=./result/project_face3.jpg>"); }void PCAFace::on_closeButton_clicked() {close(); }

    ?

    main.cpp:

    #include <QApplication> #include "pcaface.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);PCAFace w;w.show();return a.exec(); }

    ?

    ?

    ?

      實驗總結:

      通過本次實驗,對Opencv中的PCA這個類的使用有了一定的了解。

    ?

    ?

    轉載于:https://www.cnblogs.com/zhanjxcom/p/4119695.html

    總結

    以上是生活随笔為你收集整理的【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。