示例#1
0
    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)
示例#2
0
    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))
示例#3
0
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()
示例#4
0
    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
                ]))
示例#5
0
    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))
示例#6
0
    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))
示例#7
0
    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))
示例#8
0
    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)
示例#9
0
    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)
示例#10
0
    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))
示例#11
0
    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))