2008年9月6日 星期六

OpenCV線性代數-向量的表達,內積與外積運算

接下來就簡單的介紹向量,以及向量的計算了,在OpenCV內,向量的表達有很多種方式,向量是以CvMat資料結構為基準,實際上,矩陣本身就可以看成是一群的向量,它可以切割成行向量,列向量,在OpenCV內,甚至可以以通道為單位做為一個向量的表達,在一般的圖形裡,<R,G,B>格式的三通道本身就可以當做是一種向量的形式.



在下面就簡單的做內積跟外積的運算,並且用不同的方式來表達向量的運作.下面這個是用列向量的形式來做表達


列向量內積與外積的計算
#include <cv.h>
#include <stdio.h>

float Array1[]={1,2,3};
float Array2[]={4,5,6};
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels);

int main()
{
    CvMat *Matrix1=cvCreateMat(1,3,CV_32FC1);
    CvMat *Matrix2=cvCreateMat(1,3,CV_32FC1);
    CvMat *ResultMatrix=cvCreateMat(1,3,CV_32FC1);

    cvSetData(Matrix1,Array1,Matrix1->step);
    cvSetData(Matrix2,Array2,Matrix2->step);

    printf("The DotProduct is : %.f\n\n",cvDotProduct(Matrix1,Matrix2));

    printf("The CrossProduct is :\n");
    cvCrossProduct(Matrix1,Matrix2,ResultMatrix);
    PrintMatrix(ResultMatrix,1,3,1);

    system("pause");
}
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels)
{
    for(int i=0;i<Rows;i++)
    {
        for(int j=0;j<Cols;j++)
        {
            for(int k=0;k<Channels;k++)
            {
                printf("%.2f ",cvGet2D(Matrix,i,j).val[k]);
            }
        }
        printf("\n");
    }
}

執行結果:


再來就是以行向量的方式來表達,並做內積與外積的運算.


行向量內積與外積的計算
#include <cv.h>
#include <stdio.h>


float Array1[]={1,2,3};
float Array2[]={4,5,6};
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels);

int main()
{
    CvMat *Matrix1=cvCreateMat(3,1,CV_32FC1);
    CvMat *Matrix2=cvCreateMat(3,1,CV_32FC1);
    CvMat *ResultMatrix=cvCreateMat(3,1,CV_32FC1);

    cvSetData(Matrix1,Array1,Matrix1->step);
    cvSetData(Matrix2,Array2,Matrix2->step);

    printf("The DotProduct is : %.f\n\n",cvDotProduct(Matrix1,Matrix2));

    printf("The CrossProduct is :\n");
    cvCrossProduct(Matrix1,Matrix2,ResultMatrix);
    PrintMatrix(ResultMatrix,3,1,1);

    system("pause");
}
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels)
{
    for(int i=0;i<Rows;i++)
    {
        for(int j=0;j<Cols;j++)
        {
            for(int k=0;k<Channels;k++)
            {
                printf("%.2f ",cvGet2D(Matrix,i,j).val[k]);
            }
        }
        printf("\n");
    }
}

執行結果:


接著是通道的方法,並且將通道的向量來做內外積的運算.


以通道為單位的計算方式
#include <cv.h>
#include <stdio.h>


float Array1[]={1,2,3};
float Array2[]={4,5,6};
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels);

int main()
{
    CvMat *Matrix1=cvCreateMat(1,1,CV_32FC3);
    CvMat *Matrix2=cvCreateMat(1,1,CV_32FC3);
    CvMat *ResultMatrix=cvCreateMat(1,1,CV_32FC3);

    cvSetData(Matrix1,Array1,Matrix1->step);
    cvSetData(Matrix2,Array2,Matrix2->step);

    printf("The DotProduct is : %.f\n\n",cvDotProduct(Matrix1,Matrix2));

    printf("The CrossProduct is :\n");
    cvCrossProduct(Matrix1,Matrix2,ResultMatrix);
    PrintMatrix(ResultMatrix,1,1,3);

    system("pause");
}
void PrintMatrix(CvMat *Matrix,int Rows,int Cols,int Channels)
{
    for(int i=0;i<Rows;i++)
    {
        for(int j=0;j<Cols;j++)
        {
            for(int k=0;k<Channels;k++)
            {
                printf("%.2f ",cvGet2D(Matrix,i,j).val[k]);
            }
        }
        printf("\n");
    }
}

執行結果:


內積與外積的計算方式


從上面可以看的出來,向量的計算方式只有一些些微的數據有變化,在cvCreateMat()上要改變格式,在PrintMatrix()上要改變列印方式,其他的地方都是一樣,而輸出的結果也影響不大,在OpenCV上,向量的實作是實現在矩陣上,而它使用的方式也是很自由的,用這三種方式表達向量都是可行的.

cvDotProduct()
向量內積的計算,第一個引數為輸入CvMat資料結構的向量,第二個引數為輸入CvMat資料結構的向量,輸入的向量每個維度的個數必須要相等,且必須具備為向量輸入的格式,輸出為一個double型別的數據為內積計算的結果.
double cvDotProduct(輸入CvMat資料結構向量,輸入CvMat資料結構向量)

cvCrossProduct()
向量外積的計算,必須要是三維向量,且必須要為向量具備的輸入格式,第一個引數為輸入CvMat三維向量資料結構,第二個引數為輸入CvMat三維向量資料結構第三個引數為輸出CvMat三維向量外積計算結果.
cvCrossProduct(輸入CvMat三維向量資料結構,輸入CvMat三維向量資料結構,輸出CvMat三維向量資料結構)



0 意見:

Copyright 2008-2009,yester