关于直方图,这里不多介绍。这里主要对如何使用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);