def prepare_tile_low_par(self, tile): if self.args.refr is not None: tile_reference_eroded = self.get_output_path( "reference-eroded-{}.tif", tile.id) tile_spectral_features = self.get_output_path( "spectral-features-{}.tif", tile.id) tile_reference_trimmed_full = self.get_output_path( "reference-trimmed-full-{}.tif", tile.id) tile_reference_trimmed = self.get_output_path( "reference-trimmed-{}.tif", tile.id) step_args = [ "otbcli", "Trimming", self.args.buildfolder, "-progress", "false", "-alpha", self.args.alpha, "-nbsamples", 0, "-seed", self.args.rseed, "-feat", tile_spectral_features, "-ref", tile_reference_eroded, "-out", tile_reference_trimmed_full ] run_step(Step("Trimming_" + tile.id, step_args)) bm_exp = "im1b1 == -10000 ? -10000 : 0" for cl in self.args.crop_classes: bm_exp += " || im1b1 == " + str(cl) bm_exp += " ? 1 : 0" step_args = [ "otbcli_BandMath", "-progress", "false", "-il", tile_reference_trimmed_full, "-out", tile_reference_trimmed, "-exp", bm_exp ] run_step(Step("ClassifyReference_" + tile.id, step_args)) if not self.args.keepfiles: os.remove(tile_reference_trimmed_full)
def train_stratum(self, stratum): features_shapefile = self.get_output_path("features-{}.shp", stratum.id) split_features(stratum, self.args.refp, self.args.outdir) area_training_polygons = self.get_output_path( "training_polygons-{}.shp", stratum.id) area_validation_polygons = self.get_output_path( "validation_polygons-{}.shp", stratum.id) area_statistics = self.get_output_path("statistics-{}.xml", stratum.id) area_model = self.get_output_path("model-{}.txt", stratum.id) area_confmatout = self.get_output_path( "confusion-matrix-training-{}.csv", stratum.id) area_days = self.get_output_path("days-{}.txt", stratum.id) area_descriptors = [] area_prodpertile = [] for tile in stratum.tiles: area_descriptors += tile.get_descriptor_paths() area_prodpertile.append(len(tile.descriptors)) run_step( Step("SampleSelection", [ "otbcli", "SampleSelection", self.args.buildfolder, "-ref", features_shapefile, "-ratio", self.args.ratio, "-seed", self.args.rseed, "-tp", area_training_polygons, "-vp", area_validation_polygons ])) step_args = [ "otbcli", "CropTypeTrainImagesClassifier", self.args.buildfolder, "-mission", self.args.mission.name, "-nodatalabel", -10000, "-pixsize", self.args.pixsize, "-outdays", area_days, "-mode", self.args.trm, "-io.vd", area_training_polygons, "-rand", self.args.rseed, "-sample.bm", 0, "-io.confmatout", area_confmatout, "-io.out", area_model, "-sample.mt", self.args.nbtrsample, "-sample.mv", 10, "-sample.vfn", "CODE", "-sample.vtr", 0.01, "-classifier", self.args.classifier ] if self.args.red_edge: step_args += ["-rededge", "true"] step_args += ["-sp"] + self.args.sp step_args += ["-prodpertile"] + area_prodpertile step_args += ["-il"] + area_descriptors if self.args.classifier == "rf": step_args += [ "-classifier.rf.nbtrees", self.args.rfnbtrees, "-classifier.rf.min", self.args.rfmin, "-classifier.rf.max", self.args.rfmax ] else: step_args += [ "-classifier.svm.k", "rbf", "-classifier.svm.opt", 1, "-imstat", area_statistics ] run_step(Step("TrainImagesClassifier", step_args))
def main(): parser = argparse.ArgumentParser(description='Mask L4B raw maps') parser.add_argument('l4b_path', metavar='l4b-path', help='The L4B path') parser.add_argument('l4a_path', metavar='l4a-path', help='The L4A path') args = parser.parse_args() tile_id_re = re.compile(r"/crop_type_map_([0-9a-zA-Z]+)\.tif$") steps = [] for tile_crop_map in glob.glob( os.path.join(args.l4b_path, "crop_type_map_*.tif")): m = tile_id_re.search(tile_crop_map, re.IGNORECASE) if not m: continue tile_id = m.group(1) tile_mask = os.path.join(args.l4a_path, "crop-mask-segmented-{}.tif".format(tile_id)) if not os.path.exists(tile_mask): tile_mask = os.path.join(args.l4a_path, "crop_mask_map_{}.tif".format(tile_id)) if not os.path.exists(tile_mask): tile_mask = None if tile_mask is None: print("No crop mask found for tile {}".format(tile_id)) continue print("Using crop mask {} for tile {}".format(tile_mask, tile_id)) tile_crop_map_masked = os.path.join( args.l4b_path, "crop_type_map_masked_{}.tif".format(tile_id)) step_args = [ "otbcli_BandMath", "-exp", "im2b1 == 0 ? 0 : im1b1", "-il", tile_crop_map, tile_mask, "-out", format_otb_filename(tile_crop_map_masked, compression='DEFLATE'), "int16" ] steps.append([ Step("Mask by crop mask " + tile_id, step_args), Step("Nodata_" + tile_id, ["gdal_edit.py", "-a_nodata", -10000, tile_crop_map_masked]) ]) pool = multiprocessing.dummy.Pool(multiprocessing.cpu_count()) pool.map(run_step_list, steps) pool.close() pool.join()
def postprocess_tile(self, tile): if tile.crop_mask is not None: tile_crop_map = self.get_output_path("crop_type_map_{}.tif", tile.id) tile_crop_map_masked = self.get_output_path( "crop_type_map_masked_{}.tif", tile.id) step_args = [ "otbcli_BandMath", "-progress", "false", "-exp", "im2b1 == 0 ? 0 : im1b1", "-il", tile_crop_map, tile.crop_mask, "-out", format_otb_filename(tile_crop_map_masked, compression='DEFLATE'), "int16" ] run_step(Step("Mask by crop mask " + tile.id, step_args)) run_step( Step("Nodata_" + tile.id, [ "gdal_edit.py", "-a_nodata", -10000, tile_crop_map_masked ]))
def prepare_tile_high_par(self, tile): if self.args.refr is not None: tile_reference = self.get_output_path("reference-{}.tif", tile.id) tile_reference_eroded = self.get_output_path( "reference-eroded-{}.tif", tile.id) tile_spectral_features = self.get_output_path( "spectral-features-{}.tif", tile.id) ring = tile.footprint.GetGeometryRef(0) ll, ur = ring.GetPoint(3), ring.GetPoint(1) run_step( Step("PrepareReference_" + tile.id, [ "gdalwarp", "-q", "-dstnodata", 0, "-t_srs", tile.projection, "-te", ll[0], ll[1], ur[0], ur[1], "-tr", self.args.pixsize, self.args.pixsize, "-overwrite", self.args.refr, tile_reference ])) run_step( Step("Erosion_" + tile.id, [ "otbcli", "Erosion", self.args.buildfolder, "-progress", "false", "-radius", self.args.eroderad, "-in", tile_reference, "-out", tile_reference_eroded ])) step_args = [ "otbcli", "SpectralFeaturesExtraction", self.args.buildfolder, "-progress", "false", "-mission", self.args.mission.name, "-pixsize", self.args.pixsize, "-lambda", self.args.lmbd, "-out", tile_spectral_features ] if self.args.red_edge: step_args += ["-rededge", "true"] step_args += ["-il"] + tile.get_descriptor_paths() run_step(Step("SpectralFeatures_" + tile.id, step_args))
def prepare_tile_low_par(self, tile): if self.args.refr is not None: tile_reference_eroded = self.get_output_path( "reference-eroded-{}.tif", tile.id) tile_spectral_features = self.get_output_path( "spectral-features-{}.tif", tile.id) tile_reference_trimmed = self.get_output_path( "reference-trimmed-{}.tif", tile.id) step_args = [ "otbcli", "Trimming", self.args.buildfolder, "-progress", "false", "-alpha", self.args.alpha, "-nbsamples", 0, "-seed", self.args.rseed, "-feat", tile_spectral_features, "-ref", tile_reference_eroded, "-out", tile_reference_trimmed ] run_step(Step("Trimming_" + tile.id, step_args))
def validate(self, context): want_validation = self.args.refp is not None or self.args.force_validation if want_validation: for stratum in self.strata: area_statistics = self.get_output_path( "confusion-matrix-validation-{}.csv", stratum.id) area_quality_metrics = self.get_output_path( "quality-metrics-{}.txt", stratum.id) area_validation_metrics_xml = self.get_output_path( "validation-metrics-{}.xml", stratum.id) step_args = [ "otbcli", "ComputeConfusionMatrixMulti", self.args.buildfolder, "-out", area_statistics, "-nodatalabel", -10000, "-il" ] for tile in stratum.tiles: step_args.append(self.get_tile_crop_mask(tile)) if self.args.refp is not None: area_validation_polygons = self.get_output_path( "validation_polygons-{}.shp", stratum.id) step_args += [ "-ref", "vector", "-ref.vector.in", area_validation_polygons, "-ref.vector.field", "CROP" ] else: step_args += ["-ref", "raster", "-ref.raster.in"] for tile in stratum.tiles: tile_stratum_reference_trimmed = self.get_output_path( "reference-trimmed-{}-{}.tif", stratum.id, tile.id) step_args.append(tile_stratum_reference_trimmed) run_step( Step("ComputeConfusionMatrix_" + str(stratum.id), step_args, out_file=area_quality_metrics)) step_args = [ "otbcli", "XMLStatistics", self.args.buildfolder, "-root", "CropMask", "-confmat", area_statistics, "-quality", area_quality_metrics, "-out", area_validation_metrics_xml ] run_step(Step("XMLStatistics_" + str(stratum.id), step_args)) if not self.single_stratum: global_validation_metrics_xml = self.get_output_path( "validation-metrics-global.xml") if len(self.strata) > 1: global_statistics = self.get_output_path( "confusion-matrix-validation-global.csv") global_quality_metrics = self.get_output_path( "quality-metrics-global.txt") step_args = [ "otbcli", "ComputeConfusionMatrixMulti", self.args.buildfolder, "-out", global_statistics, "-nodatalabel", -10000, "-il" ] for tile in self.tiles: step_args.append(self.get_tile_crop_mask(tile)) if self.args.refp is not None: global_validation_polygons = self.get_output_path( "validation_polygons_global.shp") global_prj_file = self.get_output_path( "validation_polygons_global.prj") files = [] for stratum in self.strata: area_validation_polygons = self.get_output_path( "validation_polygons-{}.shp", stratum.id) files.append(area_validation_polygons) run_step( Step("ConcatenateVectorData", [ "otbcli_ConcatenateVectorData", "-out", global_validation_polygons, "-vd" ] + files)) first_prj_file = self.get_output_path( "validation_polygons-{}.prj", self.strata[0].id) shutil.copyfile(first_prj_file, global_prj_file) step_args += [ "-ref", "vector", "-ref.vector.in", global_validation_polygons, "-ref.vector.field", "CROP" ] else: step_args += ["-ref", "raster", "-ref.raster.in"] for tile in self.tiles: tile_reference_trimmed = self.get_output_path( "reference-trimmed-{}.tif", tile.id) step_args.append(tile_reference_trimmed) run_step( Step("ComputeConfusionMatrix_Global", step_args, out_file=global_quality_metrics)) step_args = [ "otbcli", "XMLStatistics", self.args.buildfolder, "-root", "CropMask", "-confmat", global_statistics, "-quality", global_quality_metrics, "-out", global_validation_metrics_xml ] run_step(Step("XMLStatistics_Global", step_args)) else: area_validation_metrics_xml = self.get_output_path( "validation-metrics-{}.xml", self.strata[0].id) shutil.copyfile(area_validation_metrics_xml, global_validation_metrics_xml) step_args = [ "otbcli", "ProductFormatter", self.args.buildfolder, "-destroot", self.args.targetfolder, "-fileclass", "SVT1", "-level", "L4A", "-baseline", "01.00", "-siteid", self.args.siteid, "-gipp", self.get_metadata_file(), "-processor", "cropmask" ] if self.args.refp is not None: step_args += ["-isd", self.get_in_situ_data_file()] if self.args.lut is not None: qgis_lut = self.get_output_path("qgis-color-map.txt") step_args += ["-lut", self.args.lut, "-lutqgis", qgis_lut] if self.args.outprops is not None: step_args += ["-outprops", self.args.outprops] step_args.append("-processor.cropmask.file") for tile in self.tiles: tile_crop_mask = self.get_tile_crop_mask(tile) step_args.append("TILE_" + tile.id) step_args.append(tile_crop_mask) if not self.args.skip_segmentation: step_args.append("-processor.cropmask.rawfile") for tile in self.tiles: tile_crop_mask = self.get_tile_classification_output(tile) step_args.append("TILE_" + tile.id) step_args.append(tile_crop_mask) step_args.append("-processor.cropmask.flags") for tile in self.tiles: tile_quality_flags = self.get_output_path("status_flags_{}.tif", tile.id) step_args.append("TILE_" + tile.id) step_args.append(tile_quality_flags) if want_validation: step_args.append("-processor.cropmask.quality") if not self.single_stratum: global_validation_metrics_xml = self.get_output_path( "validation-metrics-global.xml") step_args.append(global_validation_metrics_xml) for stratum in self.strata: area_validation_metrics_xml = self.get_output_path( "validation-metrics-{}.xml", stratum.id) if not self.single_stratum: step_args.append("REGION_" + str(stratum.id)) step_args.append(area_validation_metrics_xml) step_args.append("-il") step_args += self.args.input run_step(Step("ProductFormatter", step_args))
def postprocess_tile(self, tile): if self.args.skip_segmentation: return tile_crop_mask = self.get_tile_classification_output(tile) if not os.path.exists(tile_crop_mask): print( "Skipping post-processing for tile {} due to missing raw mask". format(tile.id)) return tile_ndvi = self.get_output_path("ndvi-{}.tif", tile.id) tile_pca = self.get_output_path("pca-{}.tif", tile.id) tile_smoothed = self.get_output_path("smoothed-{}.tif", tile.id) tile_smoothed_spatial = self.get_output_path("smoothed-spatial-{}.tif", tile.id) tile_segmentation = self.get_output_path("segmentation-{}.tif", tile.id) tile_segmentation_merged = self.get_output_path( "segmentation-merged-{}.tif", tile.id) tile_segmented = self.get_output_path("crop-mask-segmented-{}.tif", tile.id) if not self.args.reuse_segmentation: needs_segmentation_merged = True needs_segmentation = True needs_tile_smoothed = True needs_tile_smoothed_spatial = True needs_pca = True needs_ndvi = True else: if os.path.exists(tile_segmented): return needs_segmentation_merged = not os.path.exists( tile_segmentation_merged) needs_segmentation = needs_segmentation_merged and not os.path.exists( tile_segmentation) needs_tile_smoothed = needs_segmentation and not os.path.exists( tile_smoothed) needs_tile_smoothed_spatial = needs_segmentation and not os.path.exists( tile_smoothed_spatial) needs_pca = (needs_tile_smoothed or needs_tile_smoothed_spatial ) and not os.path.exists(tile_pca) needs_ndvi = needs_pca and not os.path.exists(tile_ndvi) if self.args.main_mission_segmentation: tile_descriptors = tile.get_mission_descriptor_paths( self.args.mission) else: tile_descriptors = tile.get_descriptor_paths() step_args = [ "otbcli", "NDVISeries", self.args.buildfolder, "-progress", "false", "-mission", self.args.mission.name, "-pixsize", self.args.pixsize, "-mode", "gapfill", "-out", tile_ndvi ] step_args += ["-il"] + tile_descriptors step_args += ["-sp"] + self.args.sp # if self.args.main_mission_segmentation: # step_args += ["-mode", "gapfillmain"] # else: # step_args += ["-mode", "gapfill"] if not needs_ndvi: print("Skipping NDVI extraction for tile {}".format(tile.id)) else: run_step(Step("NDVI Series " + tile.id, step_args)) step_args = [ "otbcli", "PrincipalComponentAnalysis", self.args.buildfolder, "-progress", "false", "-nbcomp", self.args.nbcomp, "-bv", -10000, "-in", tile_ndvi, "-out", tile_pca ] if not needs_pca: print("Skipping PCA for tile {}".format(tile.id)) else: run_step(Step("NDVI PCA " + tile.id, step_args)) if not self.args.keepfiles: os.remove(tile_ndvi) step_args = [ "otbcli_MeanShiftSmoothing", "-progress", "false", "-in", tile_pca, "-modesearch", 0, "-spatialr", self.args.spatialr, "-ranger", self.args.ranger, "-maxiter", 20, "-fout", tile_smoothed, "-foutpos", tile_smoothed_spatial ] if not needs_tile_smoothed and not needs_tile_smoothed_spatial: print("Skipping mean-shift smoothing for tile {}".format(tile.id)) else: run_step(Step("Mean-Shift Smoothing " + tile.id, step_args)) if not self.args.keepfiles: os.remove(tile_pca) step_args = [ "otbcli_LSMSSegmentation", "-progress", "false", "-in", tile_smoothed, "-inpos", tile_smoothed_spatial, "-spatialr", self.args.spatialr, "-ranger", self.args.ranger, "-minsize", 0, "-tilesizex", 1024, "-tilesizey", 1024, "-tmpdir", self.args.tmpfolder, "-out", format_otb_filename(tile_segmentation, compression='DEFLATE'), "uint32" ] if not needs_segmentation: print("Skipping segmentation for tile {}".format(tile.id)) else: run_step(Step("Segmentation " + tile.id, step_args)) step_args = [ "otbcli_LSMSSmallRegionsMerging", "-progress", "false", "-in", tile_smoothed, "-inseg", tile_segmentation, "-minsize", self.args.minsize, "-tilesizex", 1024, "-tilesizey", 1024, "-out", format_otb_filename(tile_segmentation_merged, compression='DEFLATE'), "uint32" ] if not needs_segmentation_merged: print("Skipping small regions merging for tile {}".format(tile.id)) else: run_step(Step("Small regions merging " + tile.id, step_args)) if not self.args.keepfiles: os.remove(tile_smoothed) os.remove(tile_smoothed_spatial) os.remove(tile_segmentation) step_args = [ "otbcli", "MajorityVoting", self.args.buildfolder, "-progress", "false", "-nodatasegvalue", 0, "-nodataclassifvalue", -10000, "-minarea", self.args.minarea, "-inclass", tile_crop_mask, "-inseg", tile_segmentation_merged, "-rout", format_otb_filename(tile_segmented, compression='DEFLATE'), "int16" ] run_step(Step("Majority voting " + tile.id, step_args)) if not self.args.keepfiles and not self.args.reuse_segmentation: os.remove(tile_segmentation_merged)
def classify_tile(self, tile): models = [] model_ids = [] days = [] statistics = [] for stratum in tile.strata: area_model = self.get_output_path("model-{}.txt", stratum.id) area_days = self.get_output_path("days-{}.txt", stratum.id) area_statistics = self.get_output_path("statistics-{}.xml", stratum.id) models.append(area_model) model_ids.append(stratum.id) days.append(area_days) statistics.append(area_statistics) if len(models) == 0: print("Skipping classification for tile {} due to stratum filter". format(tile.id)) return if not self.single_stratum: tile_model_mask = self.get_output_path("model-mask-{}.tif", tile.id) run_step( Step("Rasterize model mask", [ "otbcli_Rasterization", "-progress", "false", "-mode", "attribute", "-mode.attribute.field", "ID", "-in", self.args.filtered_strata, "-im", tile.reference_raster, "-out", format_otb_filename(tile_model_mask, compression='DEFLATE'), "uint8" ])) tile_crop_mask_uncompressed = self.get_output_path( "crop_mask_map_{}_uncompressed.tif", tile.id) if self.args.refp is not None: step_args = [ "otbcli", "CropMaskImageClassifier", self.args.buildfolder, "-progress", "false", "-mission", self.args.mission.name, "-pixsize", self.args.pixsize, "-bv", -10000, "-nodatalabel", -10000, "-bm", "true" if self.args.bm else "false", "-out", tile_crop_mask_uncompressed, "-indays" ] + days if self.args.red_edge: step_args += ["-rededge", "true"] step_args += ["-model"] + models step_args += ["-il"] + tile.get_descriptor_paths() if self.args.classifier == "svm": step_args += ["-imstat"] + statistics if not self.single_stratum: step_args += ["-mask", tile_model_mask] step_args += ["-modelid"] + model_ids else: tile_spectral_features = self.get_output_path( "spectral-features-{}.tif", tile.id) step_args = [ "otbcli", "MultiModelImageClassifier", self.args.buildfolder, "-progress", "false", "-in", tile_spectral_features, "-out", tile_crop_mask_uncompressed ] step_args += ["-model"] + models if not self.single_stratum: step_args += ["-mask", tile_model_mask] step_args += ["-modelid"] + model_ids run_step( Step("ImageClassifier_{}".format(tile.id), step_args, retry=True)) if not self.args.keepfiles: if not self.single_stratum: os.remove(tile_model_mask) if self.args.refp is None: tile_spectral_features = self.get_output_path( "spectral-features-{}.tif", tile.id) os.remove(tile_spectral_features) tile_crop_mask_map = self.get_tile_classification_output(tile) step_args = [ "otbcli_Convert", "-progress", "false", "-in", tile_crop_mask_uncompressed, "-out", format_otb_filename(tile_crop_mask_map, compression='DEFLATE'), "int16" ] run_step(Step("Compression_{}".format(tile.id), step_args)) if not self.args.keepfiles: os.remove(tile_crop_mask_uncompressed)
def train_stratum(self, stratum): area_model = self.get_output_path("model-{}.txt", stratum.id) area_confmatout = self.get_output_path( "confusion-matrix-training-{}.csv", stratum.id) if self.args.refp is not None: features_shapefile = self.get_output_path("features-{}.shp", stratum.id) split_features(stratum, self.args.refp, self.args.outdir) area_training_polygons = self.get_output_path( "training_polygons-{}.shp", stratum.id) area_validation_polygons = self.get_output_path( "validation_polygons-{}.shp", stratum.id) area_statistics = self.get_output_path("statistics-{}.xml", stratum.id) area_days = self.get_output_path("days-{}.txt", stratum.id) area_descriptors = [] area_prodpertile = [] for tile in stratum.tiles: area_descriptors += tile.get_descriptor_paths() area_prodpertile.append(len(tile.descriptors)) run_step( Step("SampleSelection", [ "otbcli", "SampleSelection", self.args.buildfolder, "-ref", features_shapefile, "-ratio", self.args.ratio, "-seed", self.args.rseed, "-nofilter", "true", "-tp", area_training_polygons, "-vp", area_validation_polygons ])) step_args = [ "otbcli", "CropMaskTrainImagesClassifier", self.args.buildfolder, "-progress", "false", "-mission", self.args.mission.name, "-nodatalabel", -10000, "-pixsize", self.args.pixsize, "-outdays", area_days, "-mode", self.args.trm, "-io.vd", area_training_polygons, "-rand", self.args.rseed, "-sample.bm", 0, "-io.confmatout", area_confmatout, "-io.out", area_model, "-sample.mt", self.args.nbtrsample, "-sample.mv", 10, "-sample.vfn", "CROP", "-sample.vtr", 0.01, "-window", self.args.window, "-bm", "true" if self.args.bm else "false", "-classifier", self.args.classifier ] if self.args.red_edge: step_args += ["-rededge", "true"] step_args += ["-sp"] + self.args.sp step_args += ["-prodpertile"] + area_prodpertile step_args += ["-il"] + area_descriptors if self.args.classifier == "rf": step_args += [ "-classifier.rf.nbtrees", self.args.rfnbtrees, "-classifier.rf.min", self.args.rfmin, "-classifier.rf.max", self.args.rfmax ] else: step_args += [ "-classifier.svm.k", "rbf", "-classifier.svm.opt", 1, "-imstat", area_statistics ] run_step(Step("TrainImagesClassifier", step_args)) else: for tile in stratum.tiles: tile_reference_trimmed = self.get_output_path( "reference-trimmed-{}.tif", tile.id) tile_stratum_reference_trimmed = self.get_output_path( "reference-trimmed-{}-{}.tif", stratum.id, tile.id) self.rasterize_tile_mask(stratum, tile) stratum_tile_mask = self.get_stratum_tile_mask(stratum, tile) step_args = [ "otbcli_BandMath", "-progress", "false", "-exp", "im1b1 > 0 ? im2b1 : -10000", "-il", stratum_tile_mask, tile_reference_trimmed, "-out", format_otb_filename(tile_stratum_reference_trimmed, compression='DEFLATE'), "int16" ] run_step(Step("BandMath_" + str(tile.id), step_args)) area_model = self.get_output_path("model-{}.txt", stratum.id) area_confmatout = self.get_output_path( "confusion-matrix-training-{}.csv", stratum.id) if self.args.classifier == "svm": files = [] for tile in stratum.tiles: tile_spectral_features = self.get_output_path( "spectral-features-{}.tif", tile.id) tile_stratum_spectral_features = self.get_output_path( "spectral-features-{}-{}.tif", stratum.id, tile.id) stratum_tile_mask = self.get_stratum_tile_mask( stratum, tile) step_args = [ "otbcli_BandMath", "-progress", "false", "-exp", "im1b1 > 0 ? im2b1 : -10000", "-il", stratum_tile_mask, tile_spectral_features, "-out", format_otb_filename(tile_stratum_spectral_features, compression='DEFLATE'), "int16" ] run_step(Step("BandMath_" + str(tile.id), step_args)) files.append(tile_stratum_spectral_features) step_args = [ "otbcli_ComputeImagesStatistics", "-bv", -10000, "-out", area_statistics, "-il" ] + files step_args = [ "otbcli", "TrainImagesClassifierNew", self.args.buildfolder, "-nodatalabel", -10000, "-rand", self.args.rseed, "-sample.bm", 0, "-io.confmatout", area_confmatout, "-io.out", area_model, "-sample.mt", self.args.nbtrsample, "-sample.mv", 1000, "-sample.vfn", "CROP", "-sample.vtr", 0.01, "-classifier", self.args.classifier ] if self.args.classifier == "rf": step_args += [ "-classifier.rf.nbtrees", self.args.rfnbtrees, "-classifier.rf.min", self.args.rfmin, "-classifier.rf.max", self.args.rfmax ] else: step_args += [ "-classifier.svm.k", "rbf", "-classifier.svm.opt", 1, "-imstat", area_statistics ] step_args.append("-io.rs") for tile in stratum.tiles: tile_stratum_reference_trimmed = self.get_output_path( "reference-trimmed-{}-{}.tif", stratum.id, tile.id) step_args.append(tile_stratum_reference_trimmed) step_args.append("-io.il") for tile in stratum.tiles: tile_spectral_features = self.get_output_path( "spectral-features-{}.tif", tile.id) step_args.append(tile_spectral_features) run_step(Step("TrainImagesClassifier", step_args))
def validate(self, context): for stratum in self.strata: area_validation_polygons = self.get_output_path( "validation_polygons-{}.shp", stratum.id) area_statistics = self.get_output_path( "confusion-matrix-validation-{}.csv", stratum.id) area_quality_metrics = self.get_output_path( "quality-metrics-{}.txt", stratum.id) area_validation_metrics_xml = self.get_output_path( "validation-metrics-{}.xml", stratum.id) step_args = [ "otbcli", "ComputeConfusionMatrixMulti", self.args.buildfolder, "-ref", "vector", "-ref.vector.in", area_validation_polygons, "-ref.vector.field", "CODE", "-out", area_statistics, "-nodatalabel", -10000, "-il" ] for tile in stratum.tiles: step_args.append(self.get_tile_crop_map(tile)) run_step( Step("ComputeConfusionMatrix_" + str(stratum.id), step_args, out_file=area_quality_metrics)) step_args = [ "otbcli", "XMLStatistics", self.args.buildfolder, "-root", "CropType", "-confmat", area_statistics, "-quality", area_quality_metrics, "-out", area_validation_metrics_xml ] run_step(Step("XMLStatistics_" + str(stratum.id), step_args)) if not self.single_stratum: global_validation_metrics_xml = self.get_output_path( "validation-metrics-global.xml") if len(self.strata) > 1: global_validation_polygons = self.get_output_path( "validation_polygons_global.shp") global_prj_file = self.get_output_path( "validation_polygons_global.prj") global_statistics = self.get_output_path( "confusion-matrix-validation-global.csv") global_quality_metrics = self.get_output_path( "quality-metrics-global.txt") files = [] for stratum in self.strata: area_validation_polygons = self.get_output_path( "validation_polygons-{}.shp", stratum.id) files.append(area_validation_polygons) step_args = [ "otbcli_ConcatenateVectorData", "-out", global_validation_polygons, "-vd" ] + files run_step(Step("ConcatenateVectorData", step_args)) first_prj_file = self.get_output_path( "validation_polygons-{}.prj", self.strata[0].id) shutil.copyfile(first_prj_file, global_prj_file) step_args = [ "otbcli", "ComputeConfusionMatrixMulti", self.args.buildfolder, "-ref", "vector", "-ref.vector.in", global_validation_polygons, "-ref.vector.field", "CODE", "-out", global_statistics, "-nodatalabel", -10000, "-il" ] for tile in self.tiles: step_args.append(self.get_tile_crop_map(tile)) run_step( Step("ComputeConfusionMatrix_Global", step_args, out_file=global_quality_metrics)) step_args = [ "otbcli", "XMLStatistics", self.args.buildfolder, "-root", "CropType", "-confmat", global_statistics, "-quality", global_quality_metrics, "-out", global_validation_metrics_xml ] run_step(Step("XMLStatistics_Global", step_args)) else: area_validation_metrics_xml = self.get_output_path( "validation-metrics-{}.xml", self.strata[0].id) shutil.copyfile(area_validation_metrics_xml, global_validation_metrics_xml) step_args = [ "otbcli", "ProductFormatter", self.args.buildfolder, "-destroot", self.args.targetfolder, "-fileclass", "SVT1", "-level", "L4B", "-baseline", "01.00", "-siteid", self.args.siteid, "-gipp", self.get_metadata_file(), "-isd", self.get_in_situ_data_file(), "-processor", "croptype" ] if self.args.lut is not None: qgis_lut = self.get_output_path("qgis-color-map.txt") step_args += ["-lut", self.args.lut, "-lutqgis", qgis_lut] if self.args.outprops is not None: step_args += ["-outprops", self.args.outprops] has_mask = False for tile in self.tiles: if tile.crop_mask is not None: has_mask = True break step_args.append("-processor.croptype.file") for tile in self.tiles: tile_crop_map = self.get_tile_crop_map(tile) step_args.append("TILE_" + tile.id) step_args.append(tile_crop_map) if has_mask and self.args.include_raw_map: step_args.append("-processor.croptype.rawfile") for tile in self.tiles: if tile.crop_mask is not None: tile_crop_map = self.get_output_path( "crop_type_map_{}.tif", tile.id) step_args.append("TILE_" + tile.id) step_args.append(tile_crop_map) step_args.append("-processor.croptype.flags") for tile in self.tiles: tile_quality_flags = self.get_output_path("status_flags_{}.tif", tile.id) step_args.append("TILE_" + tile.id) step_args.append(tile_quality_flags) step_args.append("-processor.croptype.quality") if not self.single_stratum: global_validation_metrics_xml = self.get_output_path( "validation-metrics-global.xml") step_args.append(global_validation_metrics_xml) for stratum in self.strata: area_validation_metrics_xml = self.get_output_path( "validation-metrics-{}.xml", stratum.id) if not self.single_stratum: step_args.append("REGION_" + str(stratum.id)) step_args.append(area_validation_metrics_xml) step_args.append("-il") step_args += self.args.input run_step(Step("ProductFormatter", step_args))