天天看點

利用GDAL和QWT繪制圖像直方圖1--Gdal統計直方圖

參考http://wangqingyun84.blog.163.com/blog/static/7908361720131250573866/

關于直方圖,這裡不多介紹。這裡主要對如何使用GDAL擷取直方圖進行說明。使用GDAL擷取直方圖的函數叫做GDALRasterBand::GetHistogram(),下面對這個函數的參數進行一個大緻的說明。函數GDALRasterBand::GetHistogram的定義如下:

CPLErrGDALRasterBand::GetHistogram ( double dfMin, double dfMax, int nBuckets, 
int * panHistogram,int bIncludeOutOfRange, int bApproxOK, 
GDALProgressFunc pfnProgress, void * pProgressData );
           

第一個參數和第二個參數,即dfMin和dfMax,這兩個參數的意思是指統計直方圖的最小值和最大值,在圖1中的話,就是這個橫向數軸的一個區間。比如一個8bit的圖像,你想統計所有的直方圖,那麼這兩個值可以設定為-0.5和255.5。至于為什麼不是0和255,是因為GDAL的這個函數是個開區間,就是如果設定為0和255的話,那麼0和255這兩個值是不會被統計的,是以需要把最小值往小減小一點,最大值往大增加一點。-0.5和255.5隻是我的習慣,你也可以用-0.1和255.1,隻要把0和255包括進去即可。如果你隻想統計128到255之間的直方圖,那麼把最小值設定為127.5即可;如果想統計0到128之間的直方圖,那麼把最大值設定為128.5即可。

第三個參數nBuckets,表示直方圖統計的份數,什麼意思呢?舉例說明一下,我要統計一個8bit的圖像的某個波段的直方圖,我希望每個灰階值都單獨統計一下,就是0有多少個,1有多少個,2有多少個,等等,那麼這樣的話,我就要把0~255(8bit圖像的像素存儲範圍)一共256個數分成256份,那麼這個參數就是256。如果我希望沒兩個灰階值統計在一起,就是0和1統計一個,2和3統計一個,一直到254和255統計一個,那麼這樣的話,份數就是128個,那麼這個值就是128。其他情況自己類比就出來了。這個參數還有一個作用,就是用來指定第四個參數的數組個數。

第四個參數panHistogram就是用來存儲直方圖的數組,這個數組的個數由第三個參數确定,如果這個數組的個數沒有第三個參數大,程式會崩潰滴,切忌,最好設定為一樣的。

第五個參數bIncludeOutOfRange,從字面意思就能看出來,就是是否統計區間外的值。從第一個和第二個參數可以得知,統計直方圖是有一個區間的。如果這個參數設定為TRUE,那麼圖像中的像元值小于最小值的像元值将被統計到直方圖數組中的第一個裡面去,圖像中的像元值大于最大值的像元會被統計到直方圖數組中的最後一個裡面去。如果設定為FALSE,那麼圖像中的像元值小于最小值的像元不進行統計,同樣,像元值超過最大值的像元值也不進行統計。

第六個參數bApproxOK,表示是否進行粗略統計。由于圖像大的話,統計直方圖會很慢,為了解決這個問題,GDAL提供了一個粗略的直方圖統計方式,就是用這個參數來進行指定。如果這個參數設定為TRUE,那麼統計直方圖的時候為了速度快,但是隻會統計一個大緻的直方圖,而不是周遊圖像中的所有像素來進行統計。如果該參數設定為FALSE,那麼統計的直方圖就是圖像的準确的直方圖,速度比較慢。

最後兩個參數pfnProgress和pProgressData表示進度條的回調函數和進度條資料。

那麼我們如何統計直方圖呢?代碼如下:

//先計算圖像的最小最大值
double pMinMax[2];
m_pDataSet->GetRasterBand(nbandIndex)->ComputeRasterMinMax(false,pMinMax);
 //再進行直方圖統計
 int panHistogram[256];
 m_pDataSet->GetRasterBand(nbandIndex)->GetHistogram(pMinMax[0]-0.5,pMinMax[1]+0.5,nBuckets,panHistogram,false,false,NULL,NULL);
           

繼續閱讀