影像讀取 並縮放
讀取大影像某一部分,並縮放到指定大小,我們有時會用如下代碼:
#include "gdal.h" #include "gdal_priv.h" #include "gdalwarper.h" void main() { GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");//support Chinese GDALDataset* readDataSet = (GDALDataset*)GDALOpen(inputFile.c_str(),GA_ReadOnly); if (readDataSet == NULL ) { return; } int width = readDataSet->GetRasterXSize(); int height = readDataSet->GetRasterYSize(); int bandCount = readDataSet->GetRasterCount(); int tilesize = 50; unsigned char* data = new unsigned char[tilesize*tilesize*bandCount]; if (readDataSet->RasterIO(GDALRWFlag::GF_Read,0,0,width,height,data,tilesize,tilesize,GDT_Byte,bandCount,NULL,0,0,0)==CPLErr::CE_Failure) { delete readDataSet;readDataSet=NULL; delete data; return; }
}
如果這里影像大小,非常大時,幾G到幾十G,上百G的時候,會可能遇到什么問題?
讓我們從RasterIO接口談起,跟其中代碼,得知
1、從影像金字塔取數據。根據縮小到的TileSize,它會從影像金字塔中取相應層級的數據。
2、取到數據后,會進行最近鄰插值。
由於最近鄰插值效果不佳,會導致得到的數據,都是相應的噪聲,麻點現象。
GDAL從2.0版本支持RasterIO接口進行插值算法的配置,僅僅進行簡單的配置,就可以解決這個問題。
GDALRasterIOExtraArg exterArg; INIT_RASTERIO_EXTRA_ARG(exterArg); exterArg.eResampleAlg = GDALRIOResampleAlg::GRIORA_Bilinear;//配置插值方法 readDataSet->RasterIO(GDALRWFlag::GF_Read,0,0,width,height,data,tilesize,tilesize,GDT_Byte,bandCount,NULL,0,0,0,&exterArg);
可以選擇的插值方法:
/*! Nearest neighbour */ GRIORA_NearestNeighbour = 0,
/*! Bilinear (2x2 kernel) */ GRIORA_Bilinear = 1,
/*! Cubic Convolution Approximation (4x4 kernel) */ GRIORA_Cubic = 2,
/*! Cubic B-Spline Approximation (4x4 kernel) */ GRIORA_CubicSpline = 3,
/*! Lanczos windowed sinc interpolation (6x6 kernel)*/ GRIORA_Lanczos = 4,
/*! Average */ GRIORA_Average = 5,
/*! Mode (the value which appears most often) */ GRIORA_Mode = 6,
/*! Gauss blurring */ GRIORA_Gauss = 7
影像寫出,如下操作:
GDALDriver *pDriver; pDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); GDALDataset* gdalDataset; gdalDataset = pDriver->Create(outputFile.c_str(),tilesize,tilesize,bandCount,GDT_Byte,NULL); gdalDataset->RasterIO(GF_Write,0,0,tilesize,tilesize,data,tilesize,tilesize,GDT_Byte,bandCount,NULL,0,0,0); GDALClose(gdalDataset); gdalDataset = NULL;
參考:https://trac.osgeo.org/gdal/wiki/rfc51_rasterio_resampling_progress
