PCA对特征点描述子降维
降維在機器學習領域其實是很重要的一部分,因為在高維情形下回出現樣本稀疏,計算距離、內積困難,是所有機器學習面臨的共同問題,被稱為維數災難(Curse of dimensionality),而降維就是解決的一個辦法,它不僅讓運算量變簡單,還因為將原始數據投影在主特征分量上可以抵抗一些噪聲的干擾。因為想通過降維來縮小圖像配準過程中特征點匹配的運算量,也在公眾號機器學習算法工程師中看到了一些降維的方法,比如PCA、核化(kernelized,應該就是核機制吧,實現非線性降維)、流行學習、度量學習。當然最成熟的還是PCA,雖然很早就出現了PCA-SIFT,但還是想先自己動手實現一下。思路是先導出Lowe格式的特征點txt文件,然后再在import的時候修改函數降維,寫入descr_pca數組中再導出,得到64維的特征點。這時再導入降維之后的數據,通過這些數據來實現圖像配準。
這時候就又出現問題了,構建kd樹的過程很慢,而且無法得到配準結果。后來才意識到自己用的boat的圖像的特征點數據卻在實驗中用的beaver圖像,當改正這個錯誤,并且導入原始的特征點數據后做實驗,結果匹配對的錯誤率很高,懷疑是不是因為stack_imgs把兩幅圖像顯示在一起,造成坐標變換的原因。但是最起碼img1部分的特征點應該正常啊,現在的情況是完全不對。。
從調試情況來看,import部分沒有問題,第一個點都是(254,297),對應的第二幅圖中檢測到的是(134,258),與txt中的數據吻合。在Lowe格式的txt特征點文件中,第一行是特征點個數和描述子維數,對每一個特征點,第一行四個數據依次是特征點的y坐標,x坐標,特征點的尺度,特征點的方向,然后是128個double型數字https://blog.csdn.net/masibuaa/article/details/9204157。問題似乎出在構建kd樹之后的尋找匹配對的過程中。Kd樹是對圖2的特征點feat2構建的,對feat1中的特征點遍歷,在kd樹中尋找對應的匹配點。找到的第一對是(3,15)-(4,20).
源碼,尤其是c語言,對指針的運用真的是好復雜。如下,在導入特征點中和對kd樹中進行knn查找的過程中分別有兩重指針和三重指針。
static int import_lowe_features( char*filename, struct feature** features )//靜態函數,不能被其他文件使用,所以其他文件也可以有相同的函數名
int kdtree_bbf_knn( struct kd_node*kd_root, struct feature* feat, int k,
?????????????????? ??? struct feature*** nbrs, int max_nn_chks )
在import_lowe_features函數中,有下面關鍵的兩句:
f = calloc( n, sizeof(struct feature) );//在內存的動態存儲區中分配n個長度為size的連續空間,函數返回一個指向分配起始地址的指針
*features = f;//相當于feature=&f??把features復數指向f //首地址賦給*features
于是,將import_features(path1, 1, &feat1);改為import_features(path1,1, import_feat1);//第三個參數是指針的指針,struct feature** import_feat1=NULL//初始化,運行的時候異常。
看來還是要用&feat1,因為源碼中原始的特征點檢測也是這么寫的:n1 = sift_features( img1, &feat1 );
后來發現在?? feat = feat1 + i;//指針的加法 之前,動態分配長度為n的內存之后,fscanf坐標值的時候就出錯了。fscanf讀取txt文件,要求txt文件編碼方式為ANSI,這個沒有出錯。
fscanf( file, " %lf %lf %lf %lf", &y, &x, &s, &o ) != 4 )//%lf是double類型輸入 fscanf返回讀取的長度
兩個格式控制符%lf之間是空格,適用于數據之間是空格,若數據之間是逗號,格式控制符之間也是逗號,這個也沒有出錯。
結果,尷尬了,一步步調試,看第一個特征點的各個參數,坐標是對的,一個個看128維描述子,發現到64的時候就跳變為第二個特征點了。真相大白,原來是自己在做導入降維后的txt文件時把d修改為64,在這里驗證128維的時候忘記改回去了。。
如下是按照lowe格式導入特征點信息做的圖像配準:
其中特征點導入費時4s左右。
這是直接對圖像做的特征點檢測和配準:
其中特征點檢測就耗時26s
回頭再看導入64維的描述子。速度奇慢,且無法完成配準。報錯說找到的匹配對太少。打開降維后的txt文件:
7875 64
297.440434 254.241265 80.338874 -1.866019
?2 01 0 0 0 0 0 -1 0 0 0 0 0 0 0 -1 0 0 0
?0 00 0 3 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0
?-1 00 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 1 0 0
?0 00 0
557.449920 181.560168 42.599985 1.464965
?4 -10 -1 0 0 0 3 0 0 1 0 0 0 0 0 -1 -1 0 0
?0 00 0 0 -2 1 0 0 0 0 0 3 1 -1 1 0 0 0 1
?0 21 0 0 0 0 -1 -3 0 -1 0 0 0 0 -1 -2 0 0 0
?0 00 -1
可以看到64個特征數據,分為20*3+4.而在導入的時候,特征點的坐標是取一行四個數值那行的前兩個值的,這樣就會把一部分描述子也誤當做坐標值和尺度大小即梯度。
Pcad 過程中對特征值和特征向量的行列數還是認識不夠,最后將result寫成方陣才不中斷。后來導出成了4*4維的描述子。這樣再導入到程序中來配準,找到500多個匹配對,但是畫不出匹配的連線。調試過程中發現匹配對也不正確,會不會是降維后kd樹中查找knn中閾值也要改變。
總結
以上是生活随笔為你收集整理的PCA对特征点描述子降维的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 耗时n年,38页《数据仓库知识体系.pd
- 下一篇: dataframe常用操作总结