def LandsatFmaskRoutine(MTLfile,toafile='toa.img',themalfile='thermal.img', anglesfile='angles.img',outfile='cloud.img', keepintermediates=False,verbose=True, tempdir='.',mincloudsize=0, cloudprobthreshold=100 * fmask.config.FmaskConfig.Eqn17CloudProbThresh, nirsnowthreshold=fmask.config.FmaskConfig.Eqn20NirSnowThresh, greensnowthreshold=fmask.config.FmaskConfig.Eqn20GreenSnowThresh, cloudbufferdistance=300,shadowbufferdistance=300): thermalInfo = fmask.config.readThermalInfoFromLandsatMTL(MTLfile) anglesInfo = fmask.config.AnglesFileInfo(anglesfile, 3, anglesfile, 2, anglesfile, 1, anglesfile, 0) mtlInfo = fmask.config.readMTLFile(MTLfile) sensor=GetLandsatSensor(MTLfile) fmaskFilenames = fmask.config.FmaskFilenames() fmaskFilenames.setTOAReflectanceFile(toafile) fmaskFilenames.setThermalFile(themalfile) fmaskFilenames.setOutputCloudMaskFile(outfile) fmaskConfig = fmask.config.FmaskConfig(sensor) saturationcheck.makeSaturationMask(fmaskConfig,'ref.img','saturationmask.img') fmaskFilenames.setSaturationMask('saturationmask.img') fmaskConfig.setThermalInfo(thermalInfo) fmaskConfig.setAnglesInfo(anglesInfo) fmaskConfig.setKeepIntermediates(keepintermediates) fmaskConfig.setVerbose(verbose) fmaskConfig.setTempDir(tempdir) fmaskConfig.setMinCloudSize(mincloudsize) fmaskConfig.setEqn17CloudProbThresh(cloudprobthreshold / 100) # Note conversion from percentage fmaskConfig.setEqn20NirSnowThresh(nirsnowthreshold) fmaskConfig.setEqn20GreenSnowThresh(greensnowthreshold) toaImgInfo = fileinfo.ImageInfo(toafile) fmaskConfig.setCloudBufferSize(int(cloudbufferdistance / toaImgInfo.xRes)) fmaskConfig.setShadowBufferSize(int(shadowbufferdistance / toaImgInfo.xRes)) fmask.fmask.doFmask(fmaskFilenames, fmaskConfig)
def mainRoutine(cmdargs): mtlInfo = config.readMTLFile(cmdargs.mtl) landsat = mtlInfo['SPACECRAFT_ID'][-1] if landsat == '4': sensor = config.FMASK_LANDSAT47 elif landsat == '5': sensor = config.FMASK_LANDSAT47 elif landsat == '7': sensor = config.FMASK_LANDSAT47 elif landsat == '8': sensor = config.FMASK_LANDSAT8 else: raise SystemExit('Unsupported Landsat sensor') # needed so the saturation function knows which # bands are visible etc. fmaskConfig = config.FmaskConfig(sensor) saturationcheck.makeSaturationMask(fmaskConfig, cmdargs.infile, cmdargs.output)
def makeSaturationMask(mtlfile, infile, outfile): """ Callable main routine """ mtlInfo = config.readMTLFile(mtlfile) landsat = mtlInfo['SPACECRAFT_ID'][-1] if landsat == '4': sensor = config.FMASK_LANDSAT47 elif landsat == '5': sensor = config.FMASK_LANDSAT47 elif landsat == '7': sensor = config.FMASK_LANDSAT47 elif landsat == '8': sensor = config.FMASK_LANDSAT8 else: raise SystemExit('Unsupported Landsat sensor') # needed so the saturation function knows which # bands are visible etc. fmaskConfig = config.FmaskConfig(sensor) saturationcheck.makeSaturationMask(fmaskConfig, infile, outfile)
def do_fmask(mtl_file, filters_enabled, tmp_dir, min_cloud_size=0, cloud_prob_thresh=0.225, cloud_buffer_size=4, shadow_buffer_size=6, cirrus_prob_ratio=0.04, nir_fill_thresh=0.02, swir2_thresh=0.03, whiteness_thresh=0.7, swir2_water_test=0.03, nir_snow_thresh=0.11, green_snow_thresh=0.1): print("Fmask:") input_dir = os.path.dirname(mtl_file) # parser mtl_file_parse = mtl2dict(mtl_file) # get the landsat version landsat_version = int(mtl_file_parse['SPACECRAFT_ID'][-1]) # set bands for reflective and thermal if landsat_version in [4, 5]: # get the reflective file names bands reflective_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [1, 2, 3, 4, 5, 7] ] # get the thermal file names bands thermal_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [6] ] # set bands for reflective and thermal if landsat_version == 7: # get the reflective file names bands reflective_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [1, 2, 3, 4, 5, 7] ] # get the thermal file names bands thermal_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_6_VCID_' + str(N)]) for N in [1, 2] ] # set bands for reflective and thermal if landsat_version == 8: # get the reflective file names bands reflective_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [1, 2, 3, 4, 5, 6, 7, 9] ] # get the thermal file names bands thermal_bands = [ os.path.join(input_dir, mtl_file_parse['FILE_NAME_BAND_' + str(N)]) for N in [10, 11] ] # set the prefer file name band for process reflective_bands = [ get_prefer_name(file_path) for file_path in reflective_bands ] thermal_bands = [get_prefer_name(file_path) for file_path in thermal_bands] ######################################## # reflective bands stack # tmp file for reflective bands stack reflective_stack_file = os.path.join(tmp_dir, "reflective_stack.tif") if not os.path.isfile(reflective_stack_file): gdal_merge.main( ["", "-separate", "-of", "GTiff", "-o", reflective_stack_file] + reflective_bands) ######################################## # thermal bands stack # tmp file for reflective bands stack thermal_stack_file = os.path.join(tmp_dir, "thermal_stack.tif") if not os.path.isfile(thermal_stack_file): gdal_merge.main( ["", "-separate", "-of", "GTiff", "-o", thermal_stack_file] + thermal_bands) ######################################## # estimates of per-pixel angles for sun # and satellite azimuth and zenith # # fmask_usgsLandsatMakeAnglesImage.py # tmp file for angles angles_file = os.path.join(tmp_dir, "angles.tif") mtlInfo = config.readMTLFile(mtl_file) imgInfo = fileinfo.ImageInfo(reflective_stack_file) corners = landsatangles.findImgCorners(reflective_stack_file, imgInfo) nadirLine = landsatangles.findNadirLine(corners) extentSunAngles = landsatangles.sunAnglesForExtent(imgInfo, mtlInfo) satAzimuth = landsatangles.satAzLeftRight(nadirLine) landsatangles.makeAnglesImage(reflective_stack_file, angles_file, nadirLine, extentSunAngles, satAzimuth, imgInfo) ######################################## # saturation mask # # fmask_usgsLandsatSaturationMask.py # tmp file for angles saturationmask_file = os.path.join(tmp_dir, "saturationmask.tif") if landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif landsat_version == 8: sensor = config.FMASK_LANDSAT8 # needed so the saturation function knows which # bands are visible etc. fmaskConfig = config.FmaskConfig(sensor) saturationcheck.makeSaturationMask(fmaskConfig, reflective_stack_file, saturationmask_file) ######################################## # top of Atmosphere reflectance # # fmask_usgsLandsatTOA.py # tmp file for toa toa_file = os.path.join(tmp_dir, "toa.tif") landsatTOA.makeTOAReflectance(reflective_stack_file, mtl_file, angles_file, toa_file) ######################################## # cloud mask # # fmask_usgsLandsatStacked.py # tmp file for cloud cloud_fmask_file = os.path.join(tmp_dir, "fmask.tif") # 1040nm thermal band should always be the first (or only) band in a # stack of Landsat thermal bands thermalInfo = config.readThermalInfoFromLandsatMTL(mtl_file) anglesInfo = config.AnglesFileInfo(angles_file, 3, angles_file, 2, angles_file, 1, angles_file, 0) if landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif landsat_version == 8: sensor = config.FMASK_LANDSAT8 fmaskFilenames = config.FmaskFilenames() fmaskFilenames.setTOAReflectanceFile(toa_file) fmaskFilenames.setThermalFile(thermal_stack_file) fmaskFilenames.setOutputCloudMaskFile(cloud_fmask_file) fmaskFilenames.setSaturationMask(saturationmask_file) # TODO: optional fmaskConfig = config.FmaskConfig(sensor) fmaskConfig.setThermalInfo(thermalInfo) fmaskConfig.setAnglesInfo(anglesInfo) fmaskConfig.setKeepIntermediates(False) fmaskConfig.setVerbose(False) fmaskConfig.setTempDir(tmp_dir) # Set the settings fmask filters from widget to FmaskConfig fmaskConfig.setMinCloudSize(min_cloud_size) fmaskConfig.setEqn17CloudProbThresh(cloud_prob_thresh) fmaskConfig.setCloudBufferSize(int(cloud_buffer_size)) fmaskConfig.setShadowBufferSize(int(shadow_buffer_size)) fmaskConfig.setCirrusProbRatio(cirrus_prob_ratio) fmaskConfig.setEqn19NIRFillThresh(nir_fill_thresh) fmaskConfig.setEqn1Swir2Thresh(swir2_thresh) fmaskConfig.setEqn2WhitenessThresh(whiteness_thresh) fmaskConfig.setEqn7Swir2Thresh(swir2_water_test) fmaskConfig.setEqn20NirSnowThresh(nir_snow_thresh) fmaskConfig.setEqn20GreenSnowThresh(green_snow_thresh) # set to 1 for all Fmask filters disabled if filters_enabled["Fmask Cloud"]: fmask.OUTCODE_CLOUD = 2 else: fmask.OUTCODE_CLOUD = 1 if filters_enabled["Fmask Shadow"]: fmask.OUTCODE_SHADOW = 3 else: fmask.OUTCODE_SHADOW = 1 if filters_enabled["Fmask Snow"]: fmask.OUTCODE_SNOW = 4 else: fmask.OUTCODE_SNOW = 1 if filters_enabled["Fmask Water"]: fmask.OUTCODE_WATER = 5 else: fmask.OUTCODE_WATER = 1 # process Fmask fmask.doFmask(fmaskFilenames, fmaskConfig) return cloud_fmask_file
def do_fmask(self, filters_enabled, min_cloud_size=0, cloud_prob_thresh=0.225, cloud_buffer_size=4, shadow_buffer_size=6, cirrus_prob_ratio=0.04, nir_fill_thresh=0.02, swir2_thresh=0.03, whiteness_thresh=0.7, swir2_water_test=0.03, nir_snow_thresh=0.11, green_snow_thresh=0.1): ######################################## # reflective bands stack # tmp file for reflective bands stack self.reflective_stack_file = os.path.join(self.tmp_dir, "reflective_stack.tif") if not os.path.isfile(self.reflective_stack_file): update_process_bar(self.process_bar, 10, self.process_status, self.tr("Making reflective bands stack...")) gdal_merge.main(["", "-separate", "-of", "GTiff", "-o", self.reflective_stack_file] + self.reflective_bands) ######################################## # thermal bands stack # tmp file for reflective bands stack self.thermal_stack_file = os.path.join(self.tmp_dir, "thermal_stack.tif") if not os.path.isfile(self.thermal_stack_file): update_process_bar(self.process_bar, 20, self.process_status, self.tr("Making thermal bands stack...")) gdal_merge.main(["", "-separate", "-of", "GTiff", "-o", self.thermal_stack_file] + self.thermal_bands) ######################################## # clipping the reflective bands stack (only if is activated selected area or shape area) self.reflective_stack_clip_file = os.path.join(self.tmp_dir, "reflective_stack_clip.tif") self.reflective_stack_for_process = self.clip(self.reflective_stack_file, self.reflective_stack_clip_file) ######################################## # clipping the thermal bands stack (only if is activated selected area or shape area) self.thermal_stack_clip_file = os.path.join(self.tmp_dir, "thermal_stack_clip.tif") self.thermal_stack_for_process = self.clip(self.thermal_stack_file, self.thermal_stack_clip_file) ######################################## # estimates of per-pixel angles for sun # and satellite azimuth and zenith # # fmask_usgsLandsatMakeAnglesImage.py # tmp file for angles self.angles_file = os.path.join(self.tmp_dir, "angles.tif") update_process_bar(self.process_bar, 30, self.process_status, self.tr("Making fmask angles file...")) mtlInfo = config.readMTLFile(self.mtl_path) imgInfo = fileinfo.ImageInfo(self.reflective_stack_for_process) corners = landsatangles.findImgCorners(self.reflective_stack_for_process, imgInfo) nadirLine = landsatangles.findNadirLine(corners) extentSunAngles = landsatangles.sunAnglesForExtent(imgInfo, mtlInfo) satAzimuth = landsatangles.satAzLeftRight(nadirLine) landsatangles.makeAnglesImage(self.reflective_stack_for_process, self.angles_file, nadirLine, extentSunAngles, satAzimuth, imgInfo) ######################################## # saturation mask # # fmask_usgsLandsatSaturationMask.py # tmp file for angles self.saturationmask_file = os.path.join(self.tmp_dir, "saturationmask.tif") update_process_bar(self.process_bar, 40, self.process_status, self.tr("Making saturation mask file...")) if self.landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 8: sensor = config.FMASK_LANDSAT8 # needed so the saturation function knows which # bands are visible etc. fmaskConfig = config.FmaskConfig(sensor) saturationcheck.makeSaturationMask(fmaskConfig, self.reflective_stack_for_process, self.saturationmask_file) ######################################## # top of Atmosphere reflectance # # fmask_usgsLandsatTOA.py # tmp file for toa self.toa_file = os.path.join(self.tmp_dir, "toa.tif") update_process_bar(self.process_bar, 50, self.process_status, self.tr("Making top of Atmosphere ref...")) landsatTOA.makeTOAReflectance(self.reflective_stack_for_process, self.mtl_path, self.angles_file, self.toa_file) ######################################## # cloud mask # # fmask_usgsLandsatStacked.py # tmp file for cloud self.cloud_fmask_file = os.path.join(self.tmp_dir, "cloud_fmask_{}.tif".format(datetime.now().strftime('%H%M%S'))) update_process_bar(self.process_bar, 70, self.process_status, self.tr("Making cloud mask with fmask...")) # 1040nm thermal band should always be the first (or only) band in a # stack of Landsat thermal bands thermalInfo = config.readThermalInfoFromLandsatMTL(self.mtl_path) anglesInfo = config.AnglesFileInfo(self.angles_file, 3, self.angles_file, 2, self.angles_file, 1, self.angles_file, 0) if self.landsat_version == 4: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 5: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 7: sensor = config.FMASK_LANDSAT47 elif self.landsat_version == 8: sensor = config.FMASK_LANDSAT8 fmaskFilenames = config.FmaskFilenames() fmaskFilenames.setTOAReflectanceFile(self.toa_file) fmaskFilenames.setThermalFile(self.thermal_stack_for_process) fmaskFilenames.setOutputCloudMaskFile(self.cloud_fmask_file) fmaskFilenames.setSaturationMask(self.saturationmask_file) # TODO: optional fmaskConfig = config.FmaskConfig(sensor) fmaskConfig.setThermalInfo(thermalInfo) fmaskConfig.setAnglesInfo(anglesInfo) fmaskConfig.setKeepIntermediates(False) fmaskConfig.setVerbose(True) fmaskConfig.setTempDir(self.tmp_dir) # Set the settings fmask filters from widget to FmaskConfig fmaskConfig.setMinCloudSize(min_cloud_size) fmaskConfig.setEqn17CloudProbThresh(cloud_prob_thresh) fmaskConfig.setCloudBufferSize(int(cloud_buffer_size)) fmaskConfig.setShadowBufferSize(int(shadow_buffer_size)) fmaskConfig.setCirrusProbRatio(cirrus_prob_ratio) fmaskConfig.setEqn19NIRFillThresh(nir_fill_thresh) fmaskConfig.setEqn1Swir2Thresh(swir2_thresh) fmaskConfig.setEqn2WhitenessThresh(whiteness_thresh) fmaskConfig.setEqn7Swir2Thresh(swir2_water_test) fmaskConfig.setEqn20NirSnowThresh(nir_snow_thresh) fmaskConfig.setEqn20GreenSnowThresh(green_snow_thresh) # set to 1 for all Fmask filters disabled if filters_enabled["Fmask Cloud"]: fmask.OUTCODE_CLOUD = 2 else: fmask.OUTCODE_CLOUD = 1 if filters_enabled["Fmask Shadow"]: fmask.OUTCODE_SHADOW = 3 else: fmask.OUTCODE_SHADOW = 1 if filters_enabled["Fmask Snow"]: fmask.OUTCODE_SNOW = 4 else: fmask.OUTCODE_SNOW = 1 if filters_enabled["Fmask Water"]: fmask.OUTCODE_WATER = 5 else: fmask.OUTCODE_WATER = 1 # process Fmask fmask.doFmask(fmaskFilenames, fmaskConfig) # save final result of masking self.cloud_masking_files.append(self.cloud_fmask_file) ### ending fmask process update_process_bar(self.process_bar, 100, self.process_status, self.tr("DONE"))