影像读取 并缩放

读取大影像某一部分,并缩放到指定大小,我们有时会用如下代码:

#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 = ;
unsigned char* data = new unsigned char[tilesize*tilesize*bandCount];
if (readDataSet->RasterIO(GDALRWFlag::GF_Read,,,width,height,data,tilesize,tilesize,GDT_Byte,bandCount,NULL,,,)==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,,,width,height,data,tilesize,tilesize,GDT_Byte,bandCount,NULL,,,,&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,,,tilesize,tilesize,data,tilesize,tilesize,GDT_Byte,bandCount,NULL,,,);
GDALClose(gdalDataset);
gdalDataset = NULL;

参考:https://trac.osgeo.org/gdal/wiki/rfc51_rasterio_resampling_progress

05-11 22:34