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》