C++ GDAL 分波段進行數據運算

原文鏈接:https://www.cnblogs.com/xiaowangba/archive/2012/02/23/6314031.html
int RGBToGRAYGDAL(const char* pszSrcFile, const char* pszDstFile, bool BIT8 = true, const char* pszFormat = "GTiff")
{
	if (pszSrcFile == NULL || pszDstFile == NULL)
		return -1;

	GDALAllRegister();
	GDALDataset *poSrcDS = (GDALDataset *)GDALOpen(pszSrcFile, GA_ReadOnly);
	if (poSrcDS == NULL)
	{
		//圖像打開失敗
		return -2;
	}

	GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
	if (poDriver == NULL)
	{
		//不能創建制定類型的文件,請檢查該文件類型GDAL是否支持創建
		GDALClose((GDALDatasetH)poSrcDS);
		return -3;
	}

	//獲取圖像寬高和波段數
	int iXSize = poSrcDS->GetRasterXSize();
	int iYSize = poSrcDS->GetRasterYSize();
	int iBandCount = poSrcDS->GetRasterCount();
	//確定輸出圖像的位數
	GDALDataType eDT = GDT_UInt16;
	if (BIT8)
		eDT = GDT_Byte;
	else
		eDT = GDT_UInt16;
	//創建16bit的數據
	GDALDataset *poDstDS = poDriver->Create(pszDstFile, iXSize, iYSize, iBandCount, eDT, NULL);
	double dGeoTrans[6] = { 0 };
	//設置仿射變換參數
	poSrcDS->GetGeoTransform(dGeoTrans);
	poDstDS->SetGeoTransform(dGeoTrans);
	//設置圖像投影信息
	poDstDS->SetProjection(poSrcDS->GetProjectionRef());
	//用於保存讀取的12bit數據
	DT_16U *pSrcData = new DT_16U[iXSize];
	if (BIT8)	//轉換爲8bit
	{
		//定義結果數據存儲空間
		DT_8U *pDstData = new DT_8U[iXSize];
		//循環波段
		for (int iBand = 1; iBand <= iBandCount; iBand++)
		{
			double adfMinMax[2] = { 0 };
			int nGotMin, nGotMax;
			GDALRasterBand *pSrcBand, *pDstBand;
			pSrcBand = poSrcDS->GetRasterBand(iBand);
			pDstBand = poDstDS->GetRasterBand(iBand);

			adfMinMax[0] = pSrcBand->GetMinimum(&nGotMin);//獲得 iBand 波段影像中的最大值和最小值,用於拉伸
			adfMinMax[1] = pSrcBand->GetMaximum(&nGotMax);
			cout << "波段 " << iBand << " 的max number :" << adfMinMax[1] << endl;
			cout << "波段 " << iBand << " 的min number :" << adfMinMax[0] << endl;

			for (int i = 0; i < iYSize; i++)	//循環圖像高
			{
				//將數據讀出來
				pSrcBand->RasterIO(GF_Read, 0, i, iXSize, 1, pSrcData, iXSize, 1, GDT_UInt16, 0, 0);
				//循環,將12bit數據專爲8bit數據,使用線性拉伸方式
				for (int j = 0; j < iXSize; j++)
				{
					//double dTemp = pSrcData[j] * 255.0 / 4000.0;
					//if (dTemp > 255.0)
					//	pDstData[j] = 255;
					//else
					//	pDstData[j] = (DT_8U)dTemp;
					double dTemp = (pSrcData[j] - adfMinMax[0]) / (adfMinMax[1] - adfMinMax[0]) * 255;
					if (dTemp > 255.0)
						pDstData[j] = 255;
					else
						pDstData[j] = (DT_8U)dTemp;

				}
				pDstBand->RasterIO(GF_Write, 0, i, iXSize, 1, pDstData, iXSize, 1, GDT_Byte, 0, 0);
			}
		}
		RELEASE(pDstData);	//釋放內存
	}
	else	//轉換爲16bit數據
	{
		//循環波段
		for (int iBand = 1; iBand <= iBandCount; iBand++)
		{
			GDALRasterBand *pSrcBand = poSrcDS->GetRasterBand(iBand);
			GDALRasterBand *pDstBand = poDstDS->GetRasterBand(iBand);
			for (int i = 0; i < iYSize; i++)	//循環圖像高
			{
				//將數據讀出來,然後寫入結果數據
				pSrcBand->RasterIO(GF_Read, 0, i, iXSize, 1, pSrcData, iXSize, 1, GDT_UInt16, 0, 0);
				pDstBand->RasterIO(GF_Write, 0, i, iXSize, 1, pSrcData, iXSize, 1, GDT_UInt16, 0, 0);
			}
		}
	}
	RELEASE(pSrcData);
	//關閉原始圖像和結果圖像
	GDALClose((GDALDatasetH)poDstDS);
	GDALClose((GDALDatasetH)poSrcDS);
	return 0;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章