opencv自帶的PCA降維應用(一)

2021-09-02 21:39:07 字數 2670 閱讀 2305

好啦,下面進入正題:

首先在降維之前我提取的vlad特徵是60*64維的,即3840維,我的庫有5063張,所以降維前我的庫的vlad特徵是5063*3840,我們給他取個名,叫vlad_all,是5063行,3840列哦,行和列不要弄混了,我想把3840維的特徵降為128維,也就是減少30倍,

最終使我的庫特徵變為5063*128,好啦,看**:

pca pca(before_pca, mat(), cv_pca_data_as_row, 128);

before_pca存的就是我降維之前的庫特徵,就是那個5063*3840,這裡不用轉置直接帶入就好,經過這一句之後,降維之後的特徵向量是128*3840的(是128行,3840列,後面我都是嚴格按照行列的順序寫的,就不再贅述啦)

即mat eigenvectors = pca.eigenvectors.clone(); 

eigenvectors裡面存的就是那個128*3840的特徵向量,注意這個矩陣不是降維後的結果奧,它只是中間產生的乙個特徵向量矩陣,這個矩陣很重要,詳細了解請參考上面的「pca的數學原理」,

好啦,下面開始最重要的:

mat vlad_all_pca = eigenvectors*vlad_all.t();

注意這裡用的是vlad_all的轉置哦,否則矩陣相乘的行和列對應不起來會中斷,下面來分析這一行最重要的**:

eigenvectors是128*3840的特徵向量,vlad_all.t()是3840*5063的庫vlad特徵的轉置,這樣就正好可以對應起來了,eigenvectors是3840列,vlad_all.t()是3840行,正好可以對應相乘,,好啦,同學們猜猜看相乘的結果vlad_all_pca存的資料行和列分別是多少,

沒錯,這個vlad_all_pca就是128*5063(視情況進行轉置,我就在轉置這一塊吃過虧),現在我們把他作為庫的新vlad特徵,這個才是講過pca降維之後的真正的庫特徵。是不是比之前的5063*3840少了好多,原本的5063*3840xml檔案是327m,

降維後vlad_all_pca的xml檔案是10.9m,對,小了30倍,也就是說速度提高30倍(當然這個說法很粗魯實際上會有很多別的時間開銷)。

//****************************原圖,讀路徑,讀xml檔案路徑三個地方都需要改,還有 pictures_num****************************

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::filesystem;

using namespace std;

using namespace cv;

//#pragma comment( lib, "opencv_highgui249d.lib")

//#pragma comment( lib, "opencv_core49d.lib")

//全域性變數們

#define numclusters 60 //聚類中心數,如果呼叫extract_vlad_features函式,在surf下numclusters不大於64,在sift情況下numclusters應該是不大於128

mat descriptor_all(0, 64, cv_32fc1);

mat vlad_all(0, 64 * numclusters, cv_32fc1);//儲存庫總體的vlad特徵,

mat centers(numclusters, 64, cv_32fc1);//其實這裡的centers不定義大小也可以,聚類結束後centers裡面自動儲存聚類結果 centers(numclusters, 128, cv_32fc1);

mat labels(0, numclusters, cv_32fc1);

mat extract_vlad_features(mat &descriptors, mat ¢ers, float alpha = 1);

float computesimilarity(mat vlad_feat_query, mat vlad_feat_train);

void extractor_alldescriptors(path&basepath);

void extractor_allvlad(char filepath[150], int n_picture);// 讀取 n_picture 張

第一張是降維之前的識別結果,後兩張是降維之後的識別結果,可以看到特徵從3840維降到128維之後識別效果好像還是挺好的,細心的同學可以看到我的資料,降維前的識別速度大概是9.8s,降維後1.3s,當然這還包括讀檔案什麼的,很多環節都可以優化的哦。

只是覺得他提取的特徵向量的行列和我的有出入,可能是我沒理解透徹吧,童鞋們怕被繞就別看他的了.

想細細研究影象檢索可以看這篇碩士**,寫的很不錯:基於gmm_vlad的影象檢索_陳曼玉

**:

PCA降維演算法

文章由兩部分構成,第一部分主要講解pca演算法的步驟,第二部分講解pca演算法的原理。那麼首先進入第一部分 pca演算法的步驟 樣本矩陣x的構成 假設待觀察變數有m個,其實相當於乙個資料在m維各維度上的座標,我們的目標是在保證比較資料之間相似性不失真的前提下,將描述資料的維度盡量減小至l維 l樣本矩...

PCA降維原理

在之前的介紹中,一幅影象只能表示乙個物件。那麼對於w x h的灰度影象,只能表示為w x h位的向量,那麼乙個有100 100的影象就需要10000維的向量空間。對於一幅人臉而言,是否所有維的資料都是有用的呢?在矩陣論當中我們知道,矩陣可以近似的表示為乙個特徵值與特徵向量的乘積。根據這個原理,如果我...

資料降維 PCA

模型原型 class sklearn.decomposition.pca n components none,copy true,whiten false 引數 copy 如果為false,則直接使用原始資料來訓練,結果會覆蓋原始資料所在的陣列 whiten 如果為true,則會將特徵向量除以n s...