您的位置:首页 > 运维架构

关于GDAL中RasterIO和OpenCV中Mat.data的关系记录

2018-01-04 19:06 267 查看
在GDAL的官方文档中,对于RasterIO的中参数列表的解释如下:(这是GDALDataset的RasterIO,GDALRasterBand的RasterIO大同小异)

CPLErr GDALDataset::RasterIO    (   GDALRWFlag  eRWFlag,
int     nXOff,
int     nYOff,
int     nXSize,
int     nYSize,
void *  pData,
int     nBufXSize,
int     nBufYSize,
GDALDataType    eBufType,
int     nBandCount,
int *   panBandMap,
GSpacing    nPixelSpace,
GSpacing    nLineSpace,
GSpacing    nBandSpace,
GDALRasterIOExtraArg *  psExtraArg
)


Parameters:

eRWFlag: Either GF_Read to read a region of data, or GF_Write to write a region of data.

nXOff: The pixel offset to the top left corner of the region of the band to be accessed. This would be zero to start from the left side.

nYOff: The line offset to the top left corner of the region of the band to be accessed. This would be zero to start from the top.

nXSize: The width of the region of the band to be accessed in pixels.

nYSize: The height of the region of the band to be accessed in lines.

pData: The buffer into which the data should be read, or from which it should be written. This buffer must contain at least nBufXSize * nBufYSize * nBandCount words of type eBufType. It is organized in left to right,top to bottom pixel order. Spacing is controlled by the nPixelSpace, and nLineSpace parameters.

nBufXSize: the width of the buffer image into which the desired region is to be read, or from which it is to be written.

nBufYSize: the height of the buffer image into which the desired region is to be read, or from which it is to be written.

eBufType: the type of the pixel values in the pData data buffer. The pixel values will automatically be translated to/from the GDALRasterBand data type as needed.

nBandCount: the number of bands being read or written.

panBandMap: the list of nBandCount band numbers being read/written. Note band numbers are 1 based. This may be NULL to select the first nBandCount bands.

nPixelSpace: The byte offset from the start of one pixel value in pData to the start of the next pixel value within a scanline. If defaulted (0) the size of the datatype eBufType is used.

nLineSpace: The byte offset from the start of one scanline in pData to the start of the next. If defaulted (0) the size of the datatype eBufType * nBufXSize is used.

nBandSpace: the byte offset from the start of one bands data to the start of the next. If defaulted (0) the value will be nLineSpace * nBufYSize implying band sequential organization of the data buffer.

psExtraArg: (new in GDAL 2.0) pointer to a GDALRasterIOExtraArg structure with additional arguments to specify resampling and progress callback, or NULL for default behaviour. The GDAL_RASTERIO_RESAMPLING configuration option can also be defined to override the default resampling to one of BILINEAR, CUBIC, CUBICSPLINE, LANCZOS, AVERAGE or MODE.

Returns:

CE_Failure if the access fails, otherwise CE_None.

对于GDALRasterBand的RasterIO,没有nBandCount、panBandMap和nBandSpace这三个参数,也就是不需要指定波段(通道)信息了,所以这里就以GDALDataset的RasterIO为例。

前面的几个参数都好理解,这里主要解释nPixelSpace、nLineSpace和nBandSpace这三个参数。

nPixelSpace指的是在pData中相邻像素的间隔

nLineSpace指的是在pData中相邻两行的间隔

nBandSpace指的是在pData中相邻两个波段(通道)的间隔

以上这些间隔都是以byte为单位

在RasterIO中,如果使用默认参数(也就是上面这三个参数传的是0),则GDAL中默认认为pData是分波段存储的图像,也就是说像下面这样:

RRRRRRRRRRRR

RRRRRRRRRRRR

RRRRRRRRRRRR

GGGGGGGGGGG

GGGGGGGGGGG

GGGGGGGGGGG

BBBBBBBBBBBBB

BBBBBBBBBBBBB

BBBBBBBBBBBBB

也就是说在pData数组中,如果是上面这样从左到右从上到下依次存储的图像像素值,直接用RasterIO中的默认参数读取图像到pData(或从pData写入图像)是没有问题的。这时候RasterIO中的这三个参数的赋值如下:

nPixelSpace = sizeof(eBufType);
nLineSpace = nPixelSpace * nBufferXSize;
nBandSpace = nLineSpace * nBufferYSize;


上面这个很好理解,nPixelSpace为图像数组类型的大小,因为同一波段的像素都是相邻的;nLineSpace是一行的大小,所以就是nPixelSpace 乘上图像一行的像素数;nBandSpace 是一个波段的大小,所以就是nLineSpace乘上图像的行数。

但是在OpenCV中,如果多个波段(通道)的数据存储在Mat中,OpenCV为了兼容多个系统(平台),所以存储结构有所不同,是在每个像素的位置上同时放置所有通道的像素值,类似下面这种样子:

RGBRGBRGBRGBRGB

RGBRGBRGBRGBRGB

RGBRGBRGBRGBRGB

…………

也就是上面的一个[RGB]就是一个像素的位置。所以这时如果要将一个多通道的Mat对象内存直接用GDAL中的RasterIO的默认参数读取就会出错,图像会花。这个时候就需要指定上面说的那三个参数如下:

nPixelSpace = nChannel * sizeof(eBufType);
nLineSpace = nPixelSpace * nBufXSize;
nBandSpcae = sizeof(eBufType);


其实也很容易理解:nPixelSpace就是数据类型大小再乘上波段(通道)的个数,因为这个时候相邻的两个相同通道的像素(比如相邻的两个R)中间的间隔就是通道数;同理nBandSpace就是通道的个数;nLineSpace就是一行的个数,这个与默认的参数中是相同的,不再赘述。

在遥感领域,上面其实是两种存储格式:GDAL中默认图像是BSQ格式,而OpenCV中默认是BIP格式,具体解释如下:

BSQ(band sequential format)是按波段保存,也就是一个波段保存后接着保存第二个波段。该格式最适于对单个波谱波段中任何部分的空间(X,Y)存取;

BIL(band interleaved by line format)是按行保存,就是保存第一个波段的第一行后接着保存第二个波段的第一行,依次类推。该格式提供了空间和波谱处理之间一种折衷方式;

BIP(band interleaved by pixel format)是按像元保存,即先保存第一个波段的第一个像元,之后保存第二波段的第一个像元,依次保存。该格式为图像数据波谱(Z) 的存取提供最佳性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  GDAL OpenCV