gdal分塊讀寫遙感影像
隨着衛星影像的分辨率逐漸提高,單景衛星的存儲量也越來越大。對於米級的數據來說,目前的個人電腦很難直接處理。因此需要用分塊的方式逐塊處理。
下面這個例子是用每次讀取10000X10000大小的數據來處理總大小爲30000X40000的影像數據。
//讀取影像
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
//m_input 輸入數據
GDALDataset *podataset = (GDALDataset *)GDALOpen(m_input, GA_ReadOnly);
//獲取投影
char const *proj = podataset->GetProjectionRef();
//獲取仿射矩陣
double geo[6];
podataset->GetGeoTransform(geo);
//讀取數據
GDALRasterBand *poBand;
poBand = podataset->GetRasterBand(1);
int Width = podataset->GetRasterXSize(); //圖像寬度
int Height = podataset->GetRasterYSize(); //圖像高度
//創建輸出文件
GDALDataset *poDstDS;
const char *pszFormat = "GTIFF";
GDALDriver *poDriver;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if (poDriver == NULL)
{
exit(1);
}
char **papszOptions = NULL;
papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "LZW");
//output_file 輸出數據
poDstDS = poDriver->Create(output_file, Width, Height, 1, GDT_Byte, papszOptions);
GDALRasterBand *outBand = poDstDS->GetRasterBand(1);
int block_size = 10000;
int row_block_num =ceil(float(Height) / block_size); //行方向上的塊數
int col_block_num = ceil(float(Width) / block_size); //列方向上的塊數
row_block_num = row_block_num == 0 ? 1 : row_block_num;
col_block_num = col_block_num == 0 ? 1 : col_block_num;
std::cout << "整景影像劃分爲:" << row_block_num << "*" << col_block_num << "個子區域" << std::endl;
int block_height, block_width;//塊的實際高和寬
for (int i = 0; i < col_block_num; i++)
{
block_width = (i == col_block_num - 1) ? (Width - i*block_size) : block_size;
for (int j = 0; j < row_block_num; j++)
{
//計算實際快的大小
block_height = (j == row_block_num - 1) ? (Height - j * block_size) : block_size;
//存儲單塊結果,如圖像識別的標籤
uint8_t *result_array = new uint8_t[block_height*block_width];
//std::cout << "開始讀取16位整型數據:" << std::endl;
unsigned short *blockdata = new unsigned short[block_height*block_width];
poBand->RasterIO(GF_Read, i*block_size, j*block_size, block_width, block_height, blockdata, \
block_width, block_height, GDT_UInt16, 0, 0);
//針對單塊數據所做的操作
//.....
delete[]blockdata;
blockdata = nullptr;
//寫入文件
outBand->RasterIO(GF_Write, i*block_size, j*block_size, block_width, block_height, result_array, \
block_width, block_height, GDT_Byte, 0, 0);
delete[]ship_array;
ship_array = nullptr;
std::cout<< i+1 << " " << j+1 << "計算結束!!!!" << std::endl;
}
}