GDAL隨記-GDALRasterBand中的API自學


簡單學習了一下GDAL中的GDALRasterBand中API的用法, 以前只用過GetRasterDateType(), RasterIO(), GetXSize(), GetYSize()這些簡單的用法, 今天簡單學習GDALRasterBand中更深入的用法, 記錄如下:

1 獲得波段統計數據
代碼如下:

//影像統計數據-GetStatistics()
int bApproxOK = false;
int bForce=true;
double pdfMin, pdfMax, pdfMean, pdfStdDev;
pBand->GetStatistics(bApproxOK, bForce, &pdfMin, &pdfMax, &pdfMean, &pdfStdDev);
cout << "pdfMin: " << pdfMin <<" " << "pdfMax: " << pdfMax << " " << "pdfMean: " << pdfMean
<< " " << "pdfStdDev: " << pdfStdDev << " " << endl;

根據API文檔說明, GetStatistics()函數原型如下:

CPLErr GDALRasterBand::GetStatistics    (int bApproxOK,
int bForce,
double * pdfMin,
double * pdfMax,
double * pdfMean,
double * pdfStdDev
)

其中, 參數列表所代表的含義為:

  • bApproxOK [in] bool型, 如果為TRUE則通過波段的overview(概覽?這是啥東西?目前沒看懂…)或者a subset of all tiles(所有瓦片的子集?這也不太懂…)得到統計數據. 反正我用的false.
  • bForce [in] bool型, 如果為FALSE的話, 統計數據只在不重新掃描波段的情況下得到. 也就是說, FALSE效率高, 但是結果不能保證. 經過試驗, 確實FALSE的結果不太穩定, 還是用TRUE為好.
  • pdfMin [out] 得到波段的最小DN值.
  • pdfMax [out] 得到波段的最大DN值
  • pdfMean [out] 得到波段的DN值均值
  • pdfStdDev [out] 得到波段的DN值標准差

經過實驗, 可以得到輸入波段的DN最大最小值, 均值和方差的數據, 還是很方便的.

2 獲得波段的DN值的最大最小值
有時候, 不需要那么多統計數據, 只需要一個最大最小值就可以, 那么可以用到這三個方法: GetMaximum(), GetMinimum()以及GDALComputeRasterMinMax(). 代碼如下:

    //波段中最大值-GetMaximum()
double max = pBand->GetMaximum(&bGotMax);
cout << "波段最大值: " << max << endl;
//波段中的最小值-GetMinimum()
double min = pBand->GetMinimum(&bGotMin);
cout << "波段最小值: " << min << endl;
double maxmin[2];
if (!(bGotMax&&bGotMin))
{
GDALComputeRasterMinMax((GDALRasterBandH)pBand, true, maxmin);
}
cout << "再次計算的最小值為: " << maxmin[0] << endl;
cout << "再次計算的最大值為: " << maxmin[1] << endl;

其中, 他們的函數原型分別為:

double GDALRasterBand::GetMaximum(int *pbSuccess = NULL )   
double GDALRasterBand::GetMinimum(int *pbSuccess = NULL )
void GDALComputeRasterMinMax(GDALRasterBandH hBand,
int bApproxOK,
double adfMinMax[2])

對於GetMaximum()和GetMinimum()的參數列表,pbSucess是bool型指針, 代表着得到最大最小值是否成功, 成功返回1, 失敗返回0. 原文中描述如下:”對於不知道文件格式的波段, 最大(最小)值將會返回波段數據類型的最大(最小)值.”
也就是說,如果GDAL不能識別你輸入影像的格式,這個GetMaximum()和GetMinimum()基本就廢了…而我輸入的影像是TIFF格式的,而且是BSQ排列的三個波段的影像,然而GDAL通過這兩個函數給我返回的結果並不正確….所以沒辦法,我只好用了GDAL中面向C語言的一個方法,GDALComputeRasterStatistics().
GDALComputeRasterStatistics()參數列表說明如下:

  • hBand [in] 輸入波段(記得如果是GDALRasterBand類型的要強制轉換到GDALRasterBandH類型).
  • bApproxOK [in] 與上面GetStatistics()中的一樣,反正我用的TRUE.
  • adfMinMax[2] [out] 輸出得到的最大最小值,adfMinMax[1]為最小,adfMinMax[2]為最大.

    用GDALComputeRasterMinMax()就得到了最大最小值,還是比較靠譜的.

3 獲得波段的直方圖
之前都不知道GDAL中還有這個功能,都是自己寫統計直方圖的方法,結果今天才發現有這么一個利器.

    //波段直方圖-GetHistogram()
cout << "輸出直方圖..." << endl;
const int DS = 1024;
GUIntBig iHistogram[DS];
pBand->GetHistogram(0-0.5, DS-0.5, DS, iHistogram, false, false, NULL, NULL);
//直方圖輸出到CSV中
FILE *pFile = fopen("BandHistogram.csv", "w");
for (int i = 0; i < DS; i++)
{
fprintf(pFile,"%d,%d\r",i,(int)iHistogram[i]);
}
fclose(pFile);
cout << "輸出完畢!"<<endl;

其中,GetHistogram()函數原型如下:

CPLErr GDALRasterBand::GetHistogram(double  dfMin,
double dfMax,
int nBuckets,
GUIntBig *panHistogram,
int bIncludeOutOfRange,
int bApproxOK,
GDALProgressFunc pfnProgress,
void *pProgressData)

參數列表解釋:

  • dfMin [in] 直方圖x軸最小DN值,在我的代碼中,我用的-0,5,這樣可以去除邊緣算不算這種蛋疼的問題.
  • dfMax [in] 直方圖x軸最大DN值,與上面類似.
  • nBuckets [in] 分多少個塊,如果要是一個灰度一級的話,nBuckets=dfMax-dfMin,以此類推.
  • panHistogram [out] 得到直方圖,注意:GUIntBig類型是GDAL中自己define的一個東西,其實就是usigned long long.
  • bIncludeOutOfRange [in] bool型,如果是TRUE的話,低於直方圖統計范圍的值全部都算在panHistogram[0]中,高於直方圖統計范圍都算在panHistogram[nBuckets-1]中;如果為FALSE,則忽略超出直方圖范圍的值.
  • bApproxOK [in] TRUE的話,返回的直方圖也可以是一個近似的,不完全的.
  • pfnProgress [in] 報告進度一個函數句柄
  • pProgressData [in] 向pfnProgress傳遞的數據.

通過這個方法,我得到了波段的直方圖,而且效率也還不錯.

參考資料:GDAL的API文檔 http://www.gdal.org/classGDALRasterBand.html#aaabf419931d0f505428f91cff54085cc


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com