SAR影像輻射定標工程化實現之COSMO-Skymod

1、定標公式

在這裏插入圖片描述

2、C++實現

算法工程
(1)解析h5文件爲tiff
(2)獲取定標參數
(3)逐點定標

2.2.1、解析h5文件,這一步可以參看之前寫的文章C++版本gdal解析HDF5格式影像數據

2.2.2、根據gdalinfo信息獲取定標參數,然後逐點定標

void Radiance_correction_cosmo(const char *origin_img,const char *geo_tif, const char *radiance_tif)
{
	/*
	COSMO輻射定標
	origin_img:原始h5文件,用來獲取定標參數
	geo_tif:解析後的tiff文件
	radiance_tif:用來存儲定標結果。
	*/

	//讀取幾何校正數據
	GDALAllRegister();
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
	GDALDataset *podataset = (GDALDataset *)GDALOpen(geo_tif, GA_ReadOnly);

	const char *proj = podataset->GetProjectionRef(); 	//獲取投影
	double geo[6];
	podataset->GetGeoTransform(geo);	//獲取仿射矩陣

	int Width = podataset->GetRasterXSize(); //圖像寬度
	int Height = podataset->GetRasterYSize(); //圖像高度
	unsigned short *blockdata = new unsigned short[Height*Width];
	ReadTiff(podataset, Height, Width, blockdata, proj, geo);

	float *radiance_data = new float[Height*Width];
	//輻射定標參數
	//neb::CJsonObject params;
	//GetRadianceCorrectionParams(geo_tif,params);
	
	//使用gdalinfo獲取雲文件信息,存儲成json格式
	GDALAllRegister();
	//添加命令參數
	char **argv = NULL;
	argv = CSLAddString(argv, "-json");
	argv = CSLAddString(argv, "-hist");
	GDALInfoOptions *opt = GDALInfoOptionsNew(argv, NULL);
	GDALDatasetH TestDs = GDALOpen(origin_img, GA_ReadOnly);
	neb::CJsonObject info = GDALInfo(TestDs, opt);
	GDALInfoOptionsFree(opt);
	
	std::string reference_slant_range;
	info["metadata"][""].Get("Reference_Slant_Range", reference_slant_range);
	float reference_slant_range_f = std::atof(reference_slant_range.data());

	std::string reference_slant_range_exponent;
	info["metadata"][""].Get("Reference_Slant_Range_Exponent", reference_slant_range_exponent);
	float reference_slant_range_exponent_f = std::atof(reference_slant_range_exponent.data());

	std::string reference_incidence_range;
	info["metadata"][""].Get("Reference_Incidence_Angle", reference_incidence_range);
	float reference_incidence_range_f = std::atof(reference_incidence_range.data());

	std::string rescaling_factor;
	info["metadata"][""].Get("Rescaling_Factor", rescaling_factor);
	float rescaling_factor_f = std::atof(rescaling_factor.data());

	std::string calibration_constant;
	info["metadata"][""].Get("S01_Calibration_Constant", calibration_constant);
	float calibration_constant_f = std::atof(calibration_constant.data());
	GDALClose(TestDs);

	float Fact = pow(reference_slant_range_f, 2 * reference_slant_range_exponent_f);
	double reference_angle = reference_incidence_range_f / 180 * M_PI;

	double molecule = 0;
	double Denominator = 0;
	int count = 0;
	for (int i = 0; i < Height; i++)
	{
		for (int j = 0; j < Width; j++)
		{
			if (blockdata[count]!=0)
			{
				molecule = double(blockdata[count]) * double(blockdata[count]) * std::sin(reference_angle)*Fact;
				Denominator = rescaling_factor_f*rescaling_factor_f*calibration_constant_f;

				radiance_data[count++] = 10 * std::log10(molecule / Denominator);
			}
			else
			{
				radiance_data[count++] = 0;
			}

		}
	}

	WriteTiff(radiance_tif, Height, Width, radiance_data, proj, geo);
	delete[]blockdata;
	delete[]radiance_data;
	blockdata = nullptr;
	radiance_data = nullptr;
	GDALClose(podataset);
}

2.2.3 讀寫文件

void ReadTiff(GDALDataset *podataset, int Height, int Width, unsigned short *data_array, const char *proj, double geo[6])
{
	//獲取投影
	proj = podataset->GetProjectionRef();

	//獲取仿射矩陣
	podataset->GetGeoTransform(geo);

	//讀取數據
	GDALRasterBand *poBand;
	poBand = podataset->GetRasterBand(1);

	//數據類型
	int data_type = poBand->GetRasterDataType();
	std::cout << "數據類型:" << data_type << std::endl;
	poBand->RasterIO(GF_Read, 0, 0, Width, Height, data_array, Width, Height, GDT_UInt16, 0, 0);

}

void WriteTiff(const char *output_file, int Height, int Width, float *data_array, const char *proj, double geo[6])
{
	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");
	poDstDS = poDriver->Create(output_file, Width, Height, 1, GDT_Float32, papszOptions);
	poDstDS->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, Width, Height, data_array, Width, Height, GDT_Float32, 0, 0);
	poDstDS->GetRasterBand(1)->SetNoDataValue(0);
	poDstDS->SetGeoTransform(geo);
	poDstDS->SetProjection(proj);

	int anOverviewList[5] = { 2, 4, 8, 16, 32 };
	poDstDS->BuildOverviews("NEAREST", 5, anOverviewList, 0, NULL, NULL, NULL);

	GDALClose(poDstDS);
}
``

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