#define CV_SVD_MODIFY_A 1
#define CV_SVD_U_T 2
#define CV_SVD_V_T 4
第一個CV_SVD_MODIFY_A是將A矩陣的空間做填充,用空間換取時間的方式做加速的運算,而後面的CV_SVD_U_T,及CV_SVD_V_T則是單純的將U跟V做轉置.接著下面的程式拿非奇異矩陣做奇異值分解並且加上cvSVD()的參數.
非奇異矩陣奇異值分解
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
void PrintMatrix(CvMat *Matrix,int Rows,int Cols);
double Array1[]={1,3,3,-3,-5,-3,3,3,1};
int main()
{
CvMat *Matrix1=cvCreateMat(3,3,CV_64FC1);
CvMat *W=cvCreateMat(3,3,CV_64FC1);
CvMat *V=cvCreateMat(3,3,CV_64FC1);
CvMat *U=cvCreateMat(3,3,CV_64FC1);
CvMat *V_T=cvCreateMat(3,3,CV_64FC1);
CvMat *ResultMatrix=cvCreateMat(3,3,CV_64FC1);
cvSetData(Matrix1,Array1,Matrix1->step);
cvSVD(Matrix1,W,U,V,CV_SVD_MODIFY_A);
printf("\nW\n");
PrintMatrix(W,W->rows,W->cols);
printf("\nU\n");
PrintMatrix(U,U->rows,U->cols);
printf("\nV\n");
PrintMatrix(V,V->rows,V->cols);
printf("\nValid\n");
cvmMul(U,W,ResultMatrix);
cvTranspose(V,V_T);
cvmMul(ResultMatrix,V_T,ResultMatrix);
PrintMatrix(ResultMatrix,ResultMatrix->rows,ResultMatrix->cols);
system("pause");
}
void PrintMatrix(CvMat *Matrix,int Rows,int Cols)
{
for(int i=0;i<Rows;i++)
{
for(int j=0;j<Cols;j++)
{
printf("%.2f ",cvGet2D(Matrix,i,j).val[0]);
}
printf("\n");
}
}
執行結果:
上面使用了CV_SVD_MODIFY_A,由上面的非奇異矩陣得知,無法求得他的Eign Value及Eigen Vector,但是可以求得它的奇異值以及它的分解矩陣,並且藉由矩陣相乘的方式計算回原矩陣.計算及驗證的方式如下
而使用了CV_SVD_V_T這個參數則可以省略掉對V做cvTranspose()轉置的步驟.
cvSVD()使用CV_SVD_V_T參數
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
void PrintMatrix(CvMat *Matrix,int Rows,int Cols);
double Array1[]={1,3,3,-3,-5,-3,3,3,1};
int main()
{
CvMat *Matrix1=cvCreateMat(3,3,CV_64FC1);
CvMat *W=cvCreateMat(3,3,CV_64FC1);
CvMat *U=cvCreateMat(3,3,CV_64FC1);
CvMat *V_T=cvCreateMat(3,3,CV_64FC1);
CvMat *ResultMatrix=cvCreateMat(3,3,CV_64FC1);
cvSetData(Matrix1,Array1,Matrix1->step);
cvSVD(Matrix1,W,U,V_T,CV_SVD_V_T);
printf("\nW\n");
PrintMatrix(W,W->rows,W->cols);
printf("\nU\n");
PrintMatrix(U,U->rows,U->cols);
printf("\nV_T\n");
PrintMatrix(V_T,V_T->rows,V_T->cols);
printf("\nValid\n");
cvmMul(U,W,ResultMatrix);
cvmMul(ResultMatrix,V_T,ResultMatrix);
PrintMatrix(ResultMatrix,ResultMatrix->rows,ResultMatrix->cols);
system("pause");
}
void PrintMatrix(CvMat *Matrix,int Rows,int Cols)
{
for(int i=0;i<Rows;i++)
{
for(int j=0;j<Cols;j++)
{
printf("%.2f ",cvGet2D(Matrix,i,j).val[0]);
}
printf("\n");
}
}
執行結果:
上面的程式碼跟前面的差別,就是直接在cvSVD()內部將V矩陣轉置,可以直接將奇異值分解做驗證,而CV_SVD_U_T亦是直接將U矩陣在內部轉置.
cvSVD()
將任何的矩陣做奇異值分解,假如要分解的矩陣是m*n,則W矩陣CvMat資料結構輸入格式必須是m*n,U矩陣CvMat資料結構輸入格式必須是m*m,V矩陣CvMat資料結構輸入格式必須是n*n,cvSVD()第一個引數為輸入目標CvMat矩陣資料結構,第二個引數為輸出W矩陣CvMat資料結構,第三個引數為U矩陣CvMat資料結構,第四個引數為V矩陣CvMat資料結構,第五個引數為cvSVD()的參數,分別為CV_SVD_MODIFY_A,CV_SVD_U_T,CV_SVD_V_T.
cvSVD(輸入CvMat資料結構,輸出W矩陣CvMat結構,輸出U矩陣CvMat結構,輸出V矩陣CvMat結構,目標參數或代號)
0 意見:
張貼留言