GDAL分块处理简单的流程
GDAL分块处理流程
使用GDAL库在编写图像处理算法时,为了提高处理的效率,经常会进行分块处理,下面的代码是使用GDAL分块处理的一个简单示例:
图像分块代码
影像分块代码,只有输入输出图像路径,对原始图像经过一定的处理,将结果写入输出图像。此处原始图像和结果图像的大小完全一致。具体流程参考下面的代码以及里面的注释部分。
#include "gdal_priv.h"
bool ImageProcess(const char* pszSrcFile, const char* pszDstFile, const char* pszFormat)
{
//注册GDAL驱动
GDALAllRegister();
//获取输出图像驱动
GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if (poDriver == NULL) //输出文件格式错误
return false;
//打开输入图像
GDALDataset *poSrcDS = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly);
if (poSrcDS == NULL) //输入文件打开失败
return false;
//获取输入图像的宽高波段书
int nXSize = poSrcDS->GetRasterXSize();
int nYSize = poSrcDS->GetRasterYSize();
int nBands = poSrcDS->GetRasterCount();
//获取输入图像仿射变换参数
double adfGeotransform[6] = { 0 };
poSrcDS->GetGeoTransform(adfGeotransform);
//获取输入图像空间参考
const char* pszProj = poSrcDS->GetProjectionRef();
GDALRasterBand *poBand = poSrcDS->GetRasterBand(1);
if (poBand == NULL) //获取输入文件中的波段失败
{
GDALClose((GDALDatasetH)poSrcDS);
return false;
}
//创建输出图像,输出图像是1个波段
GDALDataset *poDstDS = poDriver->Create(pszDstFile, nXSize, nYSize, 1, GDT_Byte, NULL);
if (poDstDS == NULL) //创建输出文件失败
{
GDALClose((GDALDatasetH)poSrcDS);
return false;
}
//设置输出图像仿射变换参数,与原图一致
poDstDS->SetGeoTransform(adfGeotransform);
//设置输出图像空间参考,与原图一致
poDstDS->SetProjection(pszProj);
int nBlockSize = 256; //分块大小
//分配输入分块缓存
unsigned char *pSrcData = new unsigned char[nBlockSize*nBlockSize*nBands];
//分配输出分块缓存
unsigned char *pDstData = new unsigned char[nBlockSize*nBlockSize];
//定义读取输入图像波段顺序
int *pBandMaps = new int[nBands];
for (int b = 0; b < nBands; b++)
pBandMaps[b] = b + 1;
//循环分块并进行处理
for (int i = 0; i < nYSize; i += nBlockSize)
{
for (int j = 0; j < nXSize; j += nBlockSize)
{
//定义两个变量来保存分块大小
int nXBK = nBlockSize;
int nYBK = nBlockSize;
//如果最下面和最右边的块不够256,剩下多少读取多少
if (i + nBlockSize > nYSize) //最下面的剩余块
nYBK = nYSize - i;
if (j + nBlockSize > nXSize) //最右侧的剩余块
nXBK = nXSize - j;
//读取原始图像块
poSrcDS->RasterIO(GF_Read, j, i, nXBK, nYBK, pSrcData, nXBK, nYBK, GDT_Byte, nBands, pBandMaps, 0, 0, 0, NULL);
//再这里填写你自己的处理算法
//pSrcData 就是读取到的分块数据,存储顺序为,先行后列,最后波段
//pDstData 就是处理后的二值图数据,存储顺序为先行后列
memcpy(pDstData, pSrcData, sizeof(unsigned char)*nXBK*nYBK);
//上面这句是一个测试,将原始图像的第一个波段数据复制到输出的图像里面
//写到结果图像
poDstDS->RasterIO(GF_Write, j, i, nXBK, nYBK, pDstData, nXBK, nYBK, GDT_Byte, 1, pBandMaps, 0, 0, 0, NULL);
}
}
//释放申请的内存
delete[]pSrcData;
delete[]pDstData;
delete[]pBandMaps;
//关闭原始图像和结果图像
GDALClose((GDALDatasetH)poSrcDS);
GDALClose((GDALDatasetH)poDstDS);
return true;
}