1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
|
import datetime import time from esa_snappy import ProductIO from esa_snappy import HashMap import os, gc from esa_snappy import GPF
def do_apply_orbit_file(source): """ 应用精确轨道文件 精确轨道文件用于提高卫星位置精度,改善几何校正质量 参数: source: 输入的SAR产品 返回: output: 应用轨道文件后的产品 """ print('\tApply orbit file...') parameters = HashMap() parameters.put('Apply-Orbit-File', True) output = GPF.createProduct('Apply-Orbit-File', parameters, source) return output
def do_thermal_noise_removal(source): """ 热噪声去除 去除Sentinel-1数据中的热噪声,特别是在图像边缘和暗区域 参数: source: 输入的SAR产品 返回: output: 去除热噪声后的产品 """ print('\tThermal noise removal...') parameters = HashMap() parameters.put('removeThermalNoise', True) output = GPF.createProduct('ThermalNoiseRemoval', parameters, source) return output
def do_calibration(source, polarization, pols): """ 辐射定标 将数字值转换为物理量(如后向散射系数sigma0) 参数: source: 输入的SAR产品 polarization: 极化模式(DH/DV/SH/SV等) pols: 极化字符串(如'VH,VV') 返回: output: 定标后的产品 """ print('\tCalibration...') parameters = HashMap() parameters.put('outputSigmaBand', True) if polarization == 'DH': parameters.put('sourceBands', 'Intensity_HH,Intensity_HV') elif polarization == 'DV': parameters.put('sourceBands', 'Intensity_VH,Intensity_VV') elif polarization == 'SH' or polarization == 'HH': parameters.put('sourceBands', 'Intensity_HH') elif polarization == 'SV': parameters.put('sourceBands', 'Intensity_VV') else: print("different polarization!") parameters.put('selectedPolarisations', pols) parameters.put('outputImageScaleInDb', False) output = GPF.createProduct("Calibration", parameters, source) return output
def do_speckle_filtering(source): """ 斑点噪声滤波 使用Lee滤波器去除SAR图像中的斑点噪声,提高图像质量 参数: source: 输入的SAR产品 返回: output: 滤波后的产品 """ print('\tSpeckle filtering...') parameters = HashMap() parameters.put('filter', 'Lee') parameters.put('SizeX', 5) parameters.put('SizeY', 5) output = GPF.createProduct('Speckle-Filter', parameters, source) return output
def do_terrain_correction(source, proj, downsample): """ 地形校正 使用数字高程模型(DEM)进行地形校正,消除地形起伏造成的几何畸变 参数: source: 输入的SAR产品 proj: 地图投影参数字符串 downsample: 是否需要降采样(1-需要降采样到40m,0-不需要) 返回: output: 地形校正后的产品 """ print('\tTerrain correction...') parameters = HashMap() parameters.put('demName', 'GETASSE30') parameters.put('imgResamplingMethod', 'BILINEAR_INTERPOLATION') parameters.put('mapProjection', proj) parameters.put('saveProjectedLocalIncidenceAngle', True) parameters.put('saveSelectedSourceBand', True) while downsample == 1: parameters.put('pixelSpacingInMeter', 40.0) break output = GPF.createProduct('Terrain-Correction', parameters, source) return output
def do_subset(source, wkt): """ 子集裁剪 根据指定的地理区域裁剪图像 参数: source: 输入的SAR产品 wkt: Well-Known Text格式的地理区域定义 返回: output: 裁剪后的产品 """ print('\tSubsetting...') parameters = HashMap() parameters.put('geoRegion', wkt) output = GPF.createProduct('Subset', parameters, source) return output
def main(): """ 主函数 - 批量处理Sentinel-1数据的完整预处理流程 处理步骤: 1. 应用精确轨道文件 2. 热噪声去除 3. 辐射定标 4. 斑点滤波 5. 地形校正 6. 子集裁剪 7. 输出为GeoTIFF格式 """ path = r'data' outpath = r's1_preprocessed' if not os.path.exists(outpath): os.makedirs(outpath) wkt = 'POLYGON((112.7083 28.937,113.4886 28.937,113.4886 29.5445,112.7083 29.5445,112.7083 28.937))' proj = 'EPSG:32649'
for folder in os.listdir(path): gc.enable() gc.collect() sentinel_1 = ProductIO.readProduct(path + "\\" + folder + "\\manifest.safe") print(sentinel_1)
loopstarttime=str(datetime.datetime.now()) print('Start time:', loopstarttime) start_time = time.time()
modestamp = folder.split("_")[1] productstamp = folder.split("_")[2] polstamp = folder.split("_")[3]
polarization = polstamp[2:4] if polarization == 'DV': pols = 'VH,VV' elif polarization == 'DH': pols = 'HH,HV' elif polarization == 'SH' or polarization == 'HH': pols = 'HH' elif polarization == 'SV': pols = 'VV' else: print("Polarization error!")
print("Starting preprocessing pipeline...") applyorbit = do_apply_orbit_file(sentinel_1) thermaremoved = do_thermal_noise_removal(applyorbit) calibrated = do_calibration(thermaremoved, polarization, pols) down_filtered = do_speckle_filtering(calibrated) del applyorbit del thermaremoved del calibrated if (modestamp == 'IW' and productstamp == 'GRDH') or (modestamp == 'EW' and productstamp == 'GRDH'): down_tercorrected = do_terrain_correction(down_filtered, proj, 1) down_subset = do_subset(down_tercorrected, wkt) del down_filtered del down_tercorrected elif modestamp == 'EW' and productstamp == 'GRDM': tercorrected = do_terrain_correction(down_filtered, proj, 0) subset = do_subset(tercorrected, wkt) del down_filtered del tercorrected else: print("Different spatial resolution is found.")
down = 1 try: down_subset except NameError: down = None if down is None: print("Writing...") ProductIO.writeProduct(subset, outpath + '\\' + folder[:-5], 'GeoTIFF') del subset elif down == 1: print("Writing undersampled image...") ProductIO.writeProduct(down_subset, outpath + '\\' + folder[:-5] + '_40', 'GeoTIFF') del down_subset else: print("Error.")
print('Done.') sentinel_1.dispose() sentinel_1.closeIO() print("--- %s seconds ---" % (time.time() - start_time))
if __name__== "__main__": main()
|