2008年7月22日 星期二

資料結構操作與運算-IplImage,CvMat的比較運算

比較運算的部份就比較複雜點,在做比較時,規定要用單通道uchar型別,如果就圖形來說,可以說是灰階圖,也可以說是單通道RGB個別值的資料結構,所以就要用到前面的cvSplit()啦,他可以比較個別的RGB數據,比較個別的灰階值,而他的輸出會是個黑白圖,非0即255的數據,這個輸出的黑白圖之後可以做為Mask遮罩之用,以下程式碼

RGB,灰階圖形的比較運算
#include <cv.h>
#include <highgui.h>


int main()
{
    IplImage *Image1,*Image2;
    IplImage *ImageCmp1,*ImageCmp2,*ImageCmp3;
    IplImage *Channel1,*Channel2,*Channel3;

    CvSize Size1;
    Image1=cvLoadImage("grotto.jpg",1);
    Image2=cvLoadImage("grotto.jpg",0);
    Size1=cvGetSize(Image1);
    ImageCmp1=cvCreateImage(Size1,IPL_DEPTH_8U,1);
    ImageCmp2=cvCreateImage(Size1,IPL_DEPTH_8U,1);
    ImageCmp3=cvCreateImage(Size1,IPL_DEPTH_8U,1);

    Channel1=cvCreateImage(Size1,IPL_DEPTH_8U,1);
    Channel2=cvCreateImage(Size1,IPL_DEPTH_8U,1);
    Channel3=cvCreateImage(Size1,IPL_DEPTH_8U,1);
    cvSplit(Image1,Channel1,Channel2,Channel3,0);

    cvCmp(Channel1,Image2,ImageCmp1,CV_CMP_LT);
    cvCmpS(Channel2,127,ImageCmp2,CV_CMP_GT);
    cvMax(Channel3,Image2,ImageCmp3);

    cvNamedWindow("CV_CMP_LT",1);
    cvShowImage("CV_CMP_LT",ImageCmp1);
    cvNamedWindow("CV_CMP_GT",1);
    cvShowImage("CV_CMP_GT",ImageCmp2);
    cvNamedWindow("Max",1);
    cvShowImage("Max",ImageCmp3);
    cvWaitKey(0);
}

執行結果:


這支程式將"grotto.jpg"圖形的通道分割成Channel1,Channel2,Channel3三個圖片,並且讀取"grotto.jpg"它的灰階值來對它的三個通道分別做比較運算,先用前面所提到的通道分割方式將他分割成三個單通道的uchar型別圖片,第一個結果為將擷取出來的藍色圖片跟灰階做小於的比較運算,只要藍色值小於灰階值則為255,其他為0,第二個為全部綠色圖形對127的值做大於的比較運算,只要綠色值大於127則為255,其他為0,第三個則是兩個單通道矩陣互相比較,找出個別最大的值做輸出,因此顯示結果不是只有兩種顏色,而為灰階的.
cvCmp()為選定兩個同樣大小的單通道uchar型別的圖形矩陣,第三個引數為輸出矩陣,輸出結果為0或255,而它第四個引數為cvCmp()的參數,被定義為

#define CV_CMP_EQ 0        (Compare Equal)
#define CV_CMP_GT 1        (Compare Greater Than)
#define CV_CMP_GE 2        (Compare Greater Equal)
#define CV_CMP_LT 3        (Compare Less Than)
#define CV_CMP_LE 4        (Compare Less Equal)
#define CV_CMP_NE 5        (Compare Not Equal)

上面的定義分別為等於,大於,大於等於,小於,小於等於,不等於的比較運算參數,而cvCmpS()的參數亦是如此,只不過cvCmpS()是對一個全一矩陣的純量積做比較運算,輸出結果也是單通道0或255,而cvMax()則是對兩個輸入的單通道uchar型別資料結構做比較運算,輸出結果並不是非黑即白.

再來就是用cvMat()來實作比較運算.

CvMat的比較運算
#include <cv.h>
#include <highgui.h>
#include <stdio.h>


uchar MatrixData1[]={255,255,255,0};
uchar MatrixData2[]={192,255,0,3};
uchar MatrixData3[]={7,233,0,255};
uchar MatrixData4[4];
void PrintMatrix(CvMat *Matrix);

int main()
{
    CvMat Matrix1=cvMat(1,4,CV_8UC1,MatrixData1);
    CvMat Matrix2=cvMat(1,4,CV_8UC1,MatrixData2);
    CvMat Matrix3=cvMat(1,4,CV_8UC1,MatrixData3);
    CvMat Matrix4=cvMat(1,4,CV_8UC1,MatrixData4);

    printf("\nMatrix Compare Equal:\n");
    cvCmp(&Matrix1,&Matrix2,&Matrix4,CV_CMP_EQ);
    PrintMatrix(&Matrix4);

    printf("\nMatrix Compare Less Equal:\n");
    cvCmpS(&Matrix3,127,&Matrix4,CV_CMP_LE);
    PrintMatrix(&Matrix4);

    printf("\nMatrix Compare Max:\n");
    cvMax(&Matrix2,&Matrix3,&Matrix4);
    PrintMatrix(&Matrix4);

    printf("\nMatrix Compare Min:\n");
    cvMin(&Matrix2,&Matrix3,&Matrix4);
    PrintMatrix(&Matrix4);

    printf("\nMatrix Compare Max Scalar(50):\n");
    cvMaxS(&Matrix2,50,&Matrix4);
    PrintMatrix(&Matrix4);

    printf("\nMatrix Compare Min Scalar(100):\n");
    cvMinS(&Matrix3,100,&Matrix4);
    PrintMatrix(&Matrix4);

    system("pause");
}

void PrintMatrix(CvMat *Matrix)
{
    for(int j=0;j<4;j++)
    {
        printf("%.f ",cvGet2D(Matrix,0,j).val[0]);
    }
    printf("\n");
}

執行結果:


上面的程式把所有比較運算的函式都列出來了,第一個cvCmp()是比較兩個矩陣內的數據相等數值,由CV_CMP_EQ參數所定義,輸出為0或255,第二個cvCmpS()是比較輸入的矩陣與全一矩陣乘127的純量積小於的數值輸出的個別數據不是0就是255,第三個cvMax()則是比較兩個矩陣最大的,輸出為兩個矩陣內個別數據的最大值,cvMin()則是相反,cvMaxS()則是輸入矩陣與全一純量積比較輸出最大的,cvMinS()則是輸入矩陣與全一純量積比較輸出最小的.以下個別說明.

1.cvCmp(&Matrix1,&Matrix2,&Matrix4,CV_CMP_EQ)


2.cvCmpS(&Matrix3,127,&Matrix4,CV_CMP_LE)


3.cvMax(&Matrix2,&Matrix3,&Matrix4)


4.cvMin(&Matrix2,&Matrix3,&Matrix4)


5.cvMaxS(&Matrix2,50,&Matrix4)


6.cvMinS(&Matrix3,100,&Matrix4)


cvCmp()
將兩個同大小單通道的IplImage結構或CvMat結構做比較運算,具有六組參數,分別為CV_CMP_EQ(等於),CV_CMP_GT(大於),CV_CMP_GE(大於等於),CV_CMP_LT(小於),CV_CMP_LE(小於等於),CV_CMP_NE(不等於)的比較運算,第一個引數,第二個引數為輸入資料結構,第三個引數為輸出資料結構,第四個引數為比較運算參數.全部矩陣都必須為uchar單通道型別
cvCmp(輸入IplImage結構或CvMat結構,輸入IplImage結構或CvMat結構,輸出IplImage結構或CvMat結構,比較運算參數)

cvCmpS()
對一個IplImage結構或CvMat結構跟全一矩陣純量積做比較運算,亦由參數決定比較方式,第一個引數為輸入資料結構,第二個引數為輸入的double型別純量,第三個引數為輸出資料結構,第四個引數為比較運算參數.全部矩陣都必須為uchar單通道型別.
cvCmpS(輸入IplImage結構或CvMat結構,輸入double型別純量,輸出IplImage結構或CvMat結構,比較運算參數)

cvMax()
對兩個IplImage結構或CvMat結構做最大值的比較運算,將兩個圖形內部數據值做比較,較大的放在輸出矩陣結構上第一個引數,第二個引數為輸入資料結構,第三個引數為輸出資料結構.全部矩陣都必須為uchar單通道型別.
cvMax(輸入IplImage結構或CvMat結構,輸入IplImage結構或CvMat結構,輸出IplImage結構或CvMat結構)

cvMin()
對兩個IplImage結構或CvMat結構做最小值的比較運算,將兩個圖形內部數據值做比較,較小的放在輸出矩陣結構上第一個引數,第二個引數為輸入資料結構,第三個引數為輸出資料結構.全部矩陣都必須為uchar單通道型別.
cvMin(輸入IplImage結構或CvMat結構,輸入IplImage結構或CvMat結構,輸出IplImage結構或CvMat結構)

cvMaxS()
對一個IplImage結構或CvMat結構跟全一矩陣純量積做最大值的比較運算,第一個引數為輸入資料結構,第二個引數為輸入的double型別純量,第三個引數為輸出資料結構.全部矩陣都必須為uchar單通道型別.
cvMaxS(輸入IplImage結構或CvMat結構,輸入double型別純量,輸出IplImage結構或CvMat結構)

cvMinS()
對一個IplImage結構或CvMat結構跟全一矩陣純量積做最小值的比較運算,第一個引數為輸入資料結構,第二個引數為輸入的double型別純量,第三個引數為輸出資料結構.全部矩陣都必須為uchar單通道型別.
cvMinS(輸入IplImage結構或CvMat結構,輸入double型別純量,輸出IplImage結構或CvMat結構)



0 意見:

Copyright 2008-2009,yester