2008年10月10日 星期五

OpenCV統計應用-平均數與標準差

平均數跟標準差是統計學裡最基本的東西,cvAvg()為平均數的計算,也支援多通道的使用,而它使用的方法如下

簡單cvAvg()實作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
int main()
{
    IplImage *Image1=cvLoadImage("grotto.jpg",1);
    CvScalar Scalar1;
    Scalar1 = cvAvg(Image1);

    printf("Blue Channel Avg is : %.f\n",Scalar1.val[0]);
    printf("Green Channel Avg is : %.f\n",Scalar1.val[1]);
    printf("Red Channel Avg is : %.f\n",Scalar1.val[2]);


    cvNamedWindow("grotto",1);
    cvShowImage("grotto",Image1);
    cvWaitKey(0);
}

執行結果:


與cvSum()相同,而它與cvSum()唯一不同的地方為它支援Mask遮罩的操作,cvAvg()將黑白圖遮罩白色的部份做平均數的統計,使用方式如下

簡單cvAvg()遮罩實作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main()
{
    IplImage *Image1=cvLoadImage("grotto.jpg",1);
    IplImage *MaskImage1=cvLoadImage("grotto_Threshold.jpg",0);
    CvScalar Scalar1;
    Scalar1 = cvAvg(Image1,MaskImage1);

    printf("Blue Channel Avg is : %.f\n",Scalar1.val[0]);
    printf("Green Channel Avg is : %.f\n",Scalar1.val[1]);
    printf("Red Channel Avg is : %.f\n",Scalar1.val[2]);


    cvNamedWindow("grotto",1);
    cvShowImage("grotto",Image1);
    cvWaitKey(0);
}

執行結果:


將之前洞穴的二值化黑白圖片當遮罩對應出白色部分做平均數的計算,而OpenCV也有另外一個算平均數的函式cvAvgSdv(),它可以同時算出平均數跟標準差,也支援Mask遮罩的實作,使用的方式如下

簡單cvAvgSdv()實作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main()
{
    IplImage *Image1=cvLoadImage("grotto.jpg",1);
    CvScalar MeanScalar;
    CvScalar StandardDeviationScalar;
    cvAvgSdv(Image1,&MeanScalar,&StandardDeviationScalar);

    printf("Blue Channel Avg is : %.f\n",MeanScalar.val[0]);
    printf("Blue Channel Standard Deviation is : %.f\n",StandardDeviationScalar.val[0]);
    printf("Green Channel Avg is : %.f\n",MeanScalar.val[1]);
    printf("Green Channel Standard Deviation is : %.f\n",StandardDeviationScalar.val[1]);
    printf("Red Channel Avg is : %.f\n",MeanScalar.val[2]);
    printf("Red Channel Standard Deviation is : %.f\n",StandardDeviationScalar.val[2]);


    cvNamedWindow("grotto",1);
    cvShowImage("grotto",Image1);
    cvWaitKey(0);
}

執行結果:


上面的是用cvAvgSdv()計算平均數跟標準差,也同樣是用CvScalar資料結構來做數值的接收,再來,就是Mask的部份

簡單cvAvgSdv()遮罩實作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main()
{
    IplImage *Image1=cvLoadImage("grotto.jpg",1);
    IplImage *MaskImage1=cvLoadImage("grotto_Threshold.jpg",0);
    CvScalar MeanScalar;
    CvScalar StandardDeviationScalar;
    cvAvgSdv(Image1,&MeanScalar,&StandardDeviationScalar,MaskImage1);

    printf("Blue Channel Avg is : %.f\n",MeanScalar.val[0]);
    printf("Blue Channel Standard Deviation is : %.f\n",StandardDeviationScalar.val[0]);
    printf("Green Channel Avg is : %.f\n",MeanScalar.val[1]);
    printf("Green Channel Standard Deviation is : %.f\n",StandardDeviationScalar.val[1]);
    printf("Red Channel Avg is : %.f\n",MeanScalar.val[2]);
    printf("Red Channel Standard Deviation is : %.f\n",StandardDeviationScalar.val[2]);


    cvNamedWindow("grotto",1);
    cvShowImage("grotto",Image1);
    cvNamedWindow("grotto_Threshold",1);
    cvShowImage("grotto_Threshold",MaskImage1);

    cvWaitKey(0);
}

執行結果:


也是跟cvAvg()一樣用單通道二值化影像做遮罩,計算平均數與標準差,也不限於圖形的輸入,實際上任何的資料數據都可以做輸入,下面就是任意一筆資料來做平均數跟標準差的計算

cvMat資料結構計算平均數標準差
#include <cv.h>
#include <highgui.h>
#include <stdio.h>


uchar Array[10]={1,2,3,4,5,6,7,8,9};
int main()
{
    CvMat *Matrix1=cvCreateMat(1,10,CV_8UC1);
    cvSetData(Matrix1,Array,Matrix1->step);

    CvScalar MeanScalar;
    CvScalar StandardDeviationScalar;
    cvAvgSdv(Matrix1,&MeanScalar,&StandardDeviationScalar);

    printf("Matrix1 Avg is : %.f\n",MeanScalar.val[0]);
    printf("Matrix1 Standard Deviation is : %.f\n",StandardDeviationScalar.val[0]);

    system("pause");
}

執行結果:


實際上,很多的函式IplImage資料結構跟CvMat資料結構都是可以共用的,包括前面的cvCountNonZero(),cvSum(),cvAvg()及cvAvgSdv().

cvAvg()
計算IplImage資料結構或CvMat資料結構的平均數,支援Mask遮罩的運算,第一個引數輸入為IplImage資料結構或CvMat資料結構,第二個引數為IplImage資料結構單通道uchar型別的遮罩對應,輸出為CvScalar資料結構
cvAvg(輸入IplImage資料結構或CvMat資料結構,輸入單通道uchar型別IplImage資料結構)

cvAvgSdv()
計算IplImage資料結構或CvMat資料結構的平均數,標準差,支援Mask通道的計算,第一個引數為輸入IplImage資料結構或CvMat資料結構,第二個引數為輸出CvScalar平均數資料結構,第三個引數為輸出CvScalar標準差資料結構,第四個引數為IplImage資料結構單通道uchar型別遮罩的輸入
cvAvgSdv(輸入IplImage資料結構或CvMat資料結構,輸出平均數CvScalar資料結構,輸出標準差CvScalar資料結構,輸入單通道uchar型別IplImage資料結構)



2008年10月7日 星期二

OpenCV統計應用-總和,計算非零

再來就是一些計數的函式啦,下面簡單的介紹一張圖形,所有數值總和以及圖形上所有非0的計算,在一些圖形數值的量測方面,稍微具有一些實質的意義.

簡單cvSum()使用
#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main()
{
    IplImage *Image1=cvLoadImage("grotto.jpg",1);
    CvScalar Scalar1;
    Scalar1 = cvSum(Image1);

    printf("Blue Channel Sum is : %.f\n",Scalar1.val[0]);
    printf("Green Channel Sum is : %.f\n",Scalar1.val[1]);
    printf("Red Channel Sum is : %.f\n",Scalar1.val[2]);


    cvNamedWindow("grotto",1);
    cvShowImage("grotto",Image1);
    cvWaitKey(0);
}

原始圖片:


執行結果:


cvSum()是計算所有圖片每個通道數據的總和,因此在這個通道為3的RGB圖,所有的總和都被計算在CvScalar資料結構上面了,cvSum()輸入為IplImage或CvMat資料結構,輸出為CvScalar的資料結構,裡面存放著RGB的總和數值,接著就是cvContNonZero()的使用.

簡單cvCountNonZero()使用
#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main()
{
    IplImage *Image1=cvLoadImage("grotto_Threshold.jpg",0);

    printf("Thresholding Non Zero is : %d\n",cvCountNonZero(Image1));

    cvNamedWindow("grotto",1);
    cvShowImage("grotto",Image1);
    cvWaitKey(0);
}

原始圖片:


執行結果:


cvCountNonZero()為計算非0的個數,只能使用在單通道的圖形,而且對於這個函式在黑白圖的使用上會比較具有意義,由於黑白圖非0即1因此計算出非0的個數同時也算出了1的個數,而cvCountNonZero(),以及cvSum()也可以支援COI(Color Of Interesting)以及ROI(Region Of Interesting)的使用,使用方式如下

cvCountNonZero()及cvSum()的ROI,COI
#include <cv.h>
#include <highgui.h>
#include <stdio.h>


int main()
{
    IplImage *Image1=cvLoadImage("grotto.jpg",1);

    cvSetImageROI(Image1,cvRect(100,100,100,100));

    cvSetImageCOI(Image1,1);
    printf("Blue Channel Non Zero is : %d\n",cvCountNonZero(Image1));
    printf("Blue Channel Sum is : %.f\n",cvSum(Image1).val[0]);

    cvSetImageCOI(Image1,2);
    printf("\nGreen Channel Non Zero is : %d\n",cvCountNonZero(Image1));
    printf("Green Channel Sum is : %.f\n",cvSum(Image1).val[0]);

    cvSetImageCOI(Image1,3);
    printf("\nRed Channel Non Zero is : %d\n",cvCountNonZero(Image1));
    printf("Red Channel Sum is : %.f\n",cvSum(Image1).val[0]);

    cvNamedWindow("grotto(ROI)",1);
    cvShowImage("grotto(ROI)",Image1);
    cvResetImageROI(Image1);
    cvNamedWindow("grotto",1);
    cvShowImage("grotto",Image1);

    cvWaitKey(0);
}

執行結果:


對於一個被選定COI的他會對於特定顏色做統計,cvCountNonZero()以及cvSum()亦是如此,而被選定ROI他會對於特定的區域做計算,因此上面的結果會是被選定的區域,加上被選定的顏色,他所計算出來的統計結果,而COI選定的顏色後,因為是單通道的,所以cvSum()計算出來的結果會被放在CvScalar資料結構val[0]的位置,這邊用cvSum(Image1).val[0]表示直接存取CvScalar資料結構val[0]的數據.

cvSum()
計算所有通道數據的總和,計算出來的結果會回傳放在CvScalar資料結構上,如果是使用單通道或是COI的話會放在CvScalar資料結構val[0]上面.輸入的引數為IplImage資料結構或CvMat資料結構.
cvSum(輸入IplImage或CvMat資料結構)

cvCountNonZero()
計算所有非0數據的總和,只支援單通道或是COI,輸入為IplImage資料結構或CvMat資料結構,輸出為int變數型別.
cvCountNonZero(輸入IplImage或CvMat資料結構)



Copyright 2008-2009,yester