最近在做遥感影像高光谱纠正部分,要求输出ENVI格式(*.img),ENVI格式影像一般包括img文件(*.img)和hdr文件(*.hdr)两部分组成
C++常规做法使用GDAL获取元数据信息,然后再设置元数据,下面这段代码是基于GDAL的,前面初始化影像部分这里就不展示了,代码如下:
char** SrcMeta = SrcRCPImg->m_SrcImg->poDataset->GetMetadataDomainList();#获取所有元数据
//输出预览元数据
if (SrcMeta != nullptr) {//遍历输出
for (int i = 0; SrcMeta[i] != nullptr; i++) {
// 遍历元数据
printf("%d:%s:", i, SrcMeta[i]);
char** testTemp = SrcRCPImg->m_SrcImg->poDataset->GetMetadata(SrcMeta[i]);
//char** testTemp = poDataset->GetMetadata(SrcMeta[i]);
//cout << testTemp << endl;
for (char** ppMetadataDomain = testTemp; *ppMetadataDomain != nullptr; ppMetadataDomain++) { cout << "- " << *ppMetadataDomain << endl; }
}
}
//只设置“ENVI”元数据信息
if (strcmp(OutImgFormat, "ENVI") == 0)
{//如果是ENVI格式,则需要把ENVI元数据拷贝出去
printf("Set ENVI Metadata!\n");
char** testTemp = SrcRCPImg->m_SrcImg->poDataset->GetMetadata("ENVI");
OutImg.poDataset->SetMetadata(testTemp, "ENVI");
}
在实际预览的时候就发现这种方法获取到的元数据不完整,把波段信息字段都丢失了,导致很多信息没有,如下图:
我使用pthon的GDAL获取元数据是一样的,这可能是GDAL的一个bug吧,于是我查阅很多资料后,发现python另一个库可以很好解决这个问题
使用方法如下,我封装成了函数
import spectral#解析hdr文件元数据库 pip install spectral
import os
def ReWriteHDR(SrcHDR_path,OrthoHDR_path,OutDir):
OutHdrPath = os.path.join(OutDir,os.path.basename(OrthoHDR_path))
HDRInfoDic = spectral.envi.read_envi_header(SrcHDR_path)#只需要*.hdr文件即可读取
OrthoHDRDic = spectral.envi.read_envi_header(OrthoHDR_path)
# HDRInfo = spectral.open_image(SrcHDR_path)#如果*.img文件存在,可以使用
# OrthoHDR = spectral.open_image(OrthoHDR_path)
NewMetaDataDic = OrthoHDRDic # 把纠正的元数据给NewMetaDataDic
# 重写新的键值对
NewMetaDataDic["band names"] = HDRInfoDic["band names"]
NewMetaDataDic["wavelength"] = HDRInfoDic["wavelength"]
NewMetaDataDic["fwhm"] = HDRInfoDic["fwhm"]
NewMetaDataDic["bbl"] = HDRInfoDic["bbl"]
spectral.envi.write_envi_header(OutHdrPath, NewMetaDataDic)
print("Success:",OutHdrPath)
if __name__ == '__main__':
SrcHDR_path = "C:/Src.hdr"
OrthoHDR_path= "C:/Ortho.hdr"
OutDir="D:/temp"
ReWriteHDR(SrcHDR_path,OrthoHDR_path,OutDir)#输出文件夹里导出了Ortho.hdr文件
print("All done")