国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

OpenCV3.0 Examples學(xué)習(xí)筆記(18)-pca.cpp-PCA類實現(xiàn)降維處理

2019-11-08 18:46:52
字體:
供稿:網(wǎng)友
這個系列的目的是通過對OpenCV示例,進一步了解OpenCV函數(shù)的使用,不涉及具體原理。目錄簡介Example運行截圖Example分析Example代碼簡介本文記錄了對OpenCV示例pca.cpp的分析。資料地址:http://docs.opencv.org/3.0.0/d2/dc0/pca_8cpp-example.html這個示例主要演示了如何使用OpenCV完成PCA降維操作。PCA(PRincipal Component Analysis)是一種常用的數(shù)據(jù)分析方法。PCA通過線性變換將原始數(shù)據(jù)變換為一組各維度線性無關(guān)的表示,可用于提取數(shù)據(jù)的主要特征分量,常用于高維數(shù)據(jù)的降維。本文主要討論OpenCV的示例pca.cpp,不涉及具體數(shù)學(xué)原理,如果讀者想進一步了解PCA原理可以參考PCA的數(shù)學(xué)原理。示例涉及PCA類構(gòu)造函數(shù),project函數(shù),backProject函數(shù),和Mat類reshape函數(shù),convertTo函數(shù)的使用。
PCA構(gòu)造函數(shù)PCA類是OpenCV實現(xiàn)主要成分分析的類,在人臉識別等機器學(xué)習(xí)的項目中大量應(yīng)用,使用前需要先實例化對象。函數(shù)原型:PCA(InputArray data, InputArray mean, int flags, int maxComponents = 0);PCA(InputArray data, InputArray mean, int flags, double retainedVariance);參數(shù)說明:data:需要PCA的數(shù)據(jù),每一行(列)表示一個樣本;mean:平均值;如果矩陣是空的(noArray()),則從數(shù)據(jù)計算; flags:操作標志,具體參數(shù)如下:                            DATA_AS_ROW :每一行表示一個樣本;                            DATA_AS_COL :每一列表示一個樣本;maxComponents :PCA應(yīng)保留的最大組件數(shù);默認情況下,所有組件都保留;retainedVariance:PCA應(yīng)保留的方差百分比。使用這個參數(shù)將讓PCA決定保留多少組件,但它將始終保持至少2。 
PCA::project函數(shù)該函數(shù)的作用是將輸入數(shù)據(jù)vec(該數(shù)據(jù)是用來提取PCA特征的原始數(shù)據(jù))投影到PCA主成分空間中去,返回每一個樣本主成分特征組成的矩陣。因為經(jīng)過PCA處理后,原始數(shù)據(jù)的維數(shù)降低了,因此原始數(shù)據(jù)集中的每一個樣本的維數(shù)都變了,由改變后的樣本集就組成了本函數(shù)的返回值。函數(shù)原型:Mat project(InputArray vec) const;參數(shù)說明:vec:參與投影(降維)的數(shù)據(jù)PS:如果選擇DATA_AS_ROW,每一行表示一個樣本,則vec也需要按此
 
PCA::backProject函數(shù)一般調(diào)用backProject()函數(shù)前需調(diào)用project()函數(shù),因為backProject()函數(shù)的參數(shù)vec為經(jīng)過PCA投影降維過后的矩陣。 因此backProject()函數(shù)的作用就是用vec來重構(gòu)原始數(shù)據(jù)集(關(guān)于該函數(shù)的本質(zhì)數(shù)學(xué)實現(xiàn)暫時還不是很了解)。函數(shù)原型:Mat backProject(InputArray vec) const;參數(shù)說明:vec:參與反投影(反降維)的數(shù)據(jù)
Mat類是OpenCV 2.0以來主要的數(shù)據(jù)類型,之前在同系列博客OpenCV3.0 Examples學(xué)習(xí)筆記(3)-cout_mat.cpp中略有涉及,示例主要涉及reshape函數(shù),convertTo函數(shù)
Mat::reshape函數(shù)該函數(shù)會為當前矩陣創(chuàng)建一個新的矩陣頭(指針),新的矩陣擁有不同的尺寸或者不同的通道數(shù),其優(yōu)點在于運算復(fù)雜度為O(1),不用復(fù)制矩陣數(shù)據(jù).正是因為不用復(fù)制數(shù)據(jù),所以在轉(zhuǎn)變過程中要保證原數(shù)據(jù)矩陣在數(shù)據(jù)上的連續(xù)性(這里的連續(xù)性是相對于原矩陣來說)函數(shù)原型:Mat reshape(int cn, int rows=0) const;參數(shù)說明:cn:新的通道數(shù);如果cn值為0表示變換前后通道數(shù)不變rows:新的行數(shù);如果rows值為0表示變換后矩陣的行數(shù)不變
Mat::convertTo函數(shù)這個函數(shù)提供點算子(像素變換)能力,通過增益(alpha)和偏置(beta)參數(shù)對圖像進行調(diào)整,我們也可以使用它完成亮度(beta)和對比度(alpha)的調(diào)整,其公式如下函數(shù)原型:void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;參數(shù)說明:m:輸出矩陣;如果在使用前沒有聲明或需要修改,會自行分配(需要贊美的能力!)。 rtype:新的矩陣類型。因此也有人使用這個函數(shù)進行類型轉(zhuǎn)換alpha:增益參數(shù),對比度beta:偏置參數(shù),亮度PS:convertTo屬于Mat的成員函數(shù)。PS2:saturate_cast用于防止溢出,結(jié)果小于0則轉(zhuǎn)為0,大于255,則轉(zhuǎn)為255。
示例涉需要通過命令行存入一個txt格式輸入文件,其格式如下:
C:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s1/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s2/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s3/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s4/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s5/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s6/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s7/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s8/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s9/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s10/1.pgmC:/Mysher/OpenCV/opencv310/opencv/sources/samples/data/att_faces/s11/1.pgm
下載地址:http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.htmlExample運行截圖
Example分析0.全局函數(shù)和變量0.1read_imgList函數(shù),從txt文件中加載pgm格式圖像static void read_imgList(const string& filename, vector<Mat>& images) {    std::ifstream file(filename.c_str(), ifstream::in);    if (!file) {        string error_message = "No valid input file was given, please check the given filename.";        CV_Error(Error::StsBadArg, error_message);    }    string line;    while (getline(file, line)) {        images.push_back(imread(line, 0));    }}注意:(1)示例中采用的樣本格式為pgm,具體見參考資料7.《PGM格式圖像詳解及處理方法》(2)getline函數(shù),從輸入流中讀入字符具體見參考資料8.《C++ getline的使用》0.2formatImagesForPCA函數(shù),將所有圖像存入一個Mat中,每一行表示一個樣本 static  Mat formatImagesForPCA(const vector<Mat> &data) {    Mat dst(static_cast<int>(data.size()), data[0].rows*data[0].cols, CV_32F);    for(unsigned int i = 0; i < data.size(); i++)    {        //Mat image_row = data[i].clone().reshape(1,1);        Mat image_row = data[i].clone().reshape(1,1);        Mat row_i = dst.row(i);        image_row.convertTo(row_i,CV_32F);        //Mat tmp(1,data[0].rows*data[0].cols, CV_32F);        //image_row.convertTo(tmp,CV_32F);    }    return dst;}注意:(1)Mat::reshape,創(chuàng)建一個新的頭,示例中將所有圖像存入一個Mat,其每一行都包含一個完整的樣本信息,此處通過reshape將圖像的Mat轉(zhuǎn)換為1行1列的向量;(2)Mat::convertTo,類型轉(zhuǎn)換,示例中只是用于復(fù)制;其中關(guān)于Mat的應(yīng)用具體間參考資料9.《opencv中關(guān)于reshape, repeat初步認識》0.3toGrayscale函數(shù),將數(shù)據(jù)轉(zhuǎn)換為可以顯示的灰度圖像格式static Mat toGrayscale(InputArray _src) {    Mat src = _src.getMat();    // only allow one channel    if(src.channels() != 1) {        CV_Error(Error::StsBadArg, "Only Matrices with one channel are supported");    }    // create and return normalized image    Mat dst;    cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);    return dst;}0.4params結(jié)構(gòu)體,用于滑動條響應(yīng)函數(shù)傳遞參數(shù)struct params{    Mat data;    int ch;    int rows;    PCA pca;    string winName;};0.5onTrackbar函數(shù),響應(yīng)滑動條操作,先將第一個樣本投影到新的基(降維),再反投影,最后灰度化static void onTrackbar(int pos, void* ptr){    cout << "Retained Variance = " << pos << "%   ";    cout << "re-calculating PCA..." << std::flush;    double var = pos / 100.0;    struct params *p = (struct params *)ptr;    p->pca = PCA(p->data, cv::Mat(), PCA::DATA_AS_ROW, var);    Mat point = p->pca.project(p->data.row(0));    Mat reconstruction = p->pca.backProject(point);    reconstruction = reconstruction.reshape(p->ch, p->rows);    reconstruction = toGrayscale(reconstruction);    imshow(p->winName, reconstruction);    cout << "done!   # of principal components: " << p->pca.eigenvectors.rows << endl;}1.main函數(shù)1.1在命令行中獲取寫有文件列表的文檔    if (argc != 2) {        cout << "usage: " << argv[0] << " <image_list.txt>" << endl;        exit(1);    }1.2將文檔目錄存入變量    // Get the path to your CSV.    string imgList = string(argv[1]);1.3聲明存儲圖像Mat對象的向量    // vector to hold the images    vector<Mat> images;1.4調(diào)用全局函數(shù)read_imgList,從txt文件中加載pgm格式圖像    // Read in the data. This can fail if not valid    try {        read_imgList(imgList, images);    } catch (cv::Exception& e) {        cerr << "Error opening file /"" << imgList << "/". Reason: " << e.msg << endl;        exit(1);    }1.5判斷如果讀取的圖像少于2,則返回    // Quit if there are not enough images for this demo.    if(images.size() <= 1) {        string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";        CV_Error(Error::StsError, error_message);    }1.6將所有圖像存入一個Mat中,每一行表示一個樣本    // Reshape and stack images into a rowMatrix    Mat data = formatImagesForPCA(images);1.7創(chuàng)建PCA對象    // perform PCA    PCA pca(data, cv::Mat(), PCA::DATA_AS_ROW, 0.95); // trackbar is initially set here, also this is a common value for retainedVariance1.8先將第一個樣本投影到新的基(降維),再反投影,最后灰度化    // Demonstration of the effect of retainedVariance on the first image    Mat point = pca.project(data.row(0)); // project into the eigenspace, thus the image becomes a "point"    Mat reconstruction = pca.backProject(point); // re-create the image from the "point"    reconstruction = reconstruction.reshape(images[0].channels(), images[0].rows); // reshape from a row vector into image shape    reconstruction = toGrayscale(reconstruction); // re-scale for displaying purposes1.9創(chuàng)建窗口    // init highgui window    string winName = "Reconstruction | press 'q' to quit";    namedWindow(winName, WINDOW_NORMAL);1.10記錄參數(shù)    // params struct to pass to the trackbar handler    params p;    p.data = data;    p.ch = images[0].channels();    p.rows = images[0].rows;    p.pca = pca;    p.winName = winName;1.11創(chuàng)建滑動條    // create the tracbar    int pos = 95;    createTrackbar("Retained Variance (%)", winName, &pos, 100, onTrackbar, (void*)&p);1.12顯示結(jié)果,如果鍵盤按鍵q響應(yīng),則推出    // display until user presses q    imshow(winName, reconstruction);    int key = 0;    while(key != 'q')        key = waitKey();參考資料:1.《Opencv起步之主成分分析(PCA)》2.《reshape函數(shù)—— Matlab和opencv的reshape函數(shù) 不同點》3.《PCA的數(shù)學(xué)原理》4.《矩陣加個角標T》5.《PCA算法學(xué)習(xí)_1(OpenCV中PCA實現(xiàn)人臉降維)》6.《Stanford機器學(xué)習(xí)---第十講. 數(shù)據(jù)降維    》7.《PGM格式圖像詳解及處理方法》8.《C++ getline的使用》9.《opencv中關(guān)于reshape, repeat初步認識》10.《opencv中Mat類型轉(zhuǎn)換 ConvertTo》11.《PCA算法學(xué)習(xí)_1(OpenCV中PCA實現(xiàn)人臉降維)》12.《有個PCA的東西》13.《cv::PCA Class Reference》14.《OpenCV中cv::Mat字節(jié)對齊方法》
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 江达县| 高邮市| 原阳县| 资兴市| 醴陵市| 靖西县| 海安县| 元谋县| 大化| 寻乌县| 石狮市| 海阳市| 高陵县| 防城港市| 樟树市| 财经| 贡觉县| 修文县| 建始县| 武强县| 灵山县| 肃北| 淮滨县| 霍城县| 阜宁县| 余姚市| 沁阳市| 通化县| 扶余县| 故城县| 大足县| 衡阳县| 米泉市| 鹤山市| 池州市| 共和县| 湘乡市| 福建省| 怀仁县| 凉城县| 龙胜|