C++ gdal分塊讀寫遙感影像

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;
		}
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章