奇異值分解的理論參見下面的連接html
http://www.cnblogs.com/pinard/p/6251584.html函數
https://blog.csdn.net/shenziheng1/article/details/52916278spa
https://blog.csdn.net/billbliss/article/details/78579308.net
https://blog.csdn.net/zhongkejingwang/article/details/430535133d
https://blog.csdn.net/u010099080/article/details/68060274code
在Matlab中的eig()函數,和Opencv中的eigen()函數,都是用來得到矩陣的特徵值和特徵矢量。而且,這兩個函數的輸入矩陣必須是對稱矩陣。htm
Matlab中的eig()函數,常見的寫法以下:blog
[V D]=eig(A);排序
D是矩陣A的特徵值組成的對角矩陣,與A是同數據類型,同尺度。V是與特徵值對應的特徵矢量組成的矩陣。class
在Opencv中的eigen()函數,常見的寫法以下:
myEigen(A,D,V);
函數中的A是輸入矩陣,D和V是輸出的特徵值矢量和特徵矢量組成的矩陣。eig()函數與eigen()函數的不一樣之處是:
一、在eigen()中的D是一個一維特徵值組成的列矢量,而且特徵值是按照降序排序;而在eig()中的D則是一個以特徵值爲對角的對角矩陣,特徵值是按照升序排序。
二、在eigen()中的V是特徵矢量組成的矩陣,矩陣中的每一行就是一個特徵矢量;而在eig()中的V則是以特徵矢量組成的矩陣,矩陣中的每一列便是一個特徵矢量。
下面是同一個實例,在Matlab中和Opencv中的比較:
首先是Matlab中的eig函數的實例代碼:
clear; clc; A=[1,2,3; 2,5,6; 3,6,9]; [V D]=eig(A); A_r=V*D*V';
輸入結果以下:
下面是Opencv中eigen函數的實例代碼:
//爲方便與Matlab中的eig()函數比較,我把eigen封裝在一個函數裏,並將特徵值矢量轉換成對角矩陣,與Matlab中相似
void myEigen(Mat&A,Mat&D,Mat&V) { eigen(A,D,V); Mat E=Mat::eye(A.size(),A.type()); for(int i=0;i<A.rows;i++) { E.at<double>(i,i)=D.at<double>(0,i); } D=E.clone(); } const double eps=2.224e-16; int main() { Mat A=(Mat_<double>(3,3)<< 1,2,3, 2,5,6, 3,6,9); Mat D,V; myEigen(A,D,V); Mat A_r=V.t()*D*V; cout<<"原矩陣 A ="<<endl<<A<<endl; cout<<"重構矩陣A_r="<<endl<<A_r<<endl<<endl; cout<<"D="<<endl<<D<<endl; cout<<"V="<<endl<<V<<endl; return 0; }
輸出結果以下:
比較Matlab和Opencv中的D、V值:
Opencv中V的第一列,與Matlab中V的第一行數值一直,但排序相反,其它行列對比也基本一致。