Beispiel #1
0
 def test_get_labels_rgb(self):
     data = np.zeros((10, 10, 3), dtype=np.uint8)
     data[7:, 7:, :] = [1, 1, 1]
     raster_source = MockRasterSource([0, 1, 2], 3)
     raster_source.set_raster(data)
     rgb_class_config = ClassConfig(names=['a'], colors=['#010101'])
     rgb_class_config.ensure_null_class()
     label_source = SemanticSegmentationLabelSource(
         raster_source=raster_source, rgb_class_config=rgb_class_config)
     with label_source.activate():
         window = Box.make_square(7, 7, 3)
         labels = label_source.get_labels(window=window)
         label_arr = labels.get_label_arr(window)
         expected_label_arr = np.zeros((3, 3))
         np.testing.assert_array_equal(label_arr, expected_label_arr)
Beispiel #2
0
    def _test_class_inf(self, props, exp_class_ids, default_class_id=None):
        geojson = {
            'type':
            'FeatureCollection',
            'features': [{
                'properties': props,
                'geometry': {
                    'type': 'Point',
                    'coordinates': [1, 1]
                }
            }]
        }
        json_to_file(geojson, self.uri)

        class_config = ClassConfig(names=['building', 'car', 'tree'])
        class_id_to_filter = {
            0: ['==', 'type', 'building'],
            1: ['any', ['==', 'type', 'car'], ['==', 'type', 'auto']]
        }
        vs_cfg = GeoJSONVectorSourceConfig(
            uri=self.uri,
            class_id_to_filter=class_id_to_filter,
            default_class_id=default_class_id)
        vs = vs_cfg.build(class_config, IdentityCRSTransformer())
        trans_geojson = vs.get_geojson()
        class_ids = [
            f['properties']['class_id'] for f in trans_geojson['features']
        ]
        self.assertEqual(class_ids, exp_class_ids)
Beispiel #3
0
    def test_accounts_for_aoi(self):
        class_config = ClassConfig(names=['car', 'building', 'background'])

        label_source_uri = data_file_path('evaluator/cc-label-filtered.json')
        label_source_cfg = ChipClassificationLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=label_source_uri,
                                                    default_class_id=None))

        label_store_uri = data_file_path('evaluator/cc-label-full.json')
        label_store_cfg = ChipClassificationGeoJSONStoreConfig(
            uri=label_store_uri)

        raster_source_uri = data_file_path('evaluator/cc-label-img-blank.tif')
        raster_source_cfg = RasterioSourceConfig(uris=[raster_source_uri])

        aoi_uri = data_file_path('evaluator/cc-label-aoi.json')
        s = SceneConfig(id='test',
                        raster_source=raster_source_cfg,
                        label_source=label_source_cfg,
                        label_store=label_store_cfg,
                        aoi_uris=[aoi_uri])

        with rv_config.get_tmp_dir() as tmp_dir:
            scene = s.build(class_config, tmp_dir)
            output_uri = os.path.join(tmp_dir, 'eval.json')

            evaluator = ChipClassificationEvaluatorConfig(
                output_uri=output_uri).build(class_config)
            evaluator.process([scene], tmp_dir)

            overall = file_to_json(output_uri)['overall']
            for item in overall:
                self.assertEqual(item['f1'], 1.0)
Beispiel #4
0
 def setUp(self):
     self.crs_transformer = IdentityCRSTransformer()
     self.extent = Box.make_square(0, 0, 10)
     self.tmp_dir_obj = rv_config.get_tmp_dir()
     self.tmp_dir = self.tmp_dir_obj.name
     self.class_id = 0
     self.background_class_id = 1
     self.line_buffer = 1
     self.class_config = ClassConfig(names=['a'])
     self.uri = join(self.tmp_dir, 'tmp.json')
Beispiel #5
0
    def setUp(self):
        self.crs_transformer = DoubleCRSTransformer()
        self.geojson = {
            'type':
            'FeatureCollection',
            'features': [{
                'type': 'Feature',
                'geometry': {
                    'type':
                    'MultiPolygon',
                    'coordinates': [[[[0., 0.], [0., 2.], [2., 2.], [2., 0.],
                                      [0., 0.]]]]
                },
                'properties': {
                    'class_name': 'car',
                    'class_id': 0,
                    'score': 0.0
                }
            }, {
                'type': 'Feature',
                'geometry': {
                    'type':
                    'Polygon',
                    'coordinates': [[[2., 2.], [2., 4.], [4., 4.], [4., 2.],
                                     [2., 2.]]]
                },
                'properties': {
                    'score': 0.0,
                    'class_name': 'house',
                    'class_id': 1
                }
            }]
        }

        self.class_config = ClassConfig(names=['car', 'house'])

        self.box1 = Box.make_square(0, 0, 4)
        self.box2 = Box.make_square(4, 4, 4)
        self.class_id1 = 0
        self.class_id2 = 1
        self.background_class_id = 2

        geoms = []
        for f in self.geojson['features']:
            g = shape(f['geometry'])
            g.class_id = f['properties']['class_id']
            geoms.append(g)
        self.str_tree = STRtree(geoms)

        self.file_name = 'labels.json'
        self.tmp_dir = rv_config.get_tmp_dir()
        self.uri = os.path.join(self.tmp_dir.name, self.file_name)
        json_to_file(self.geojson, self.uri)
Beispiel #6
0
 def transform_geojson(self,
                       geojson,
                       line_bufs=None,
                       point_bufs=None,
                       crs_transformer=None,
                       to_map_coords=False):
     if crs_transformer is None:
         crs_transformer = IdentityCRSTransformer()
     class_config = ClassConfig(names=['building'])
     json_to_file(geojson, self.uri)
     cfg = GeoJSONVectorSourceConfig(uri=self.uri,
                                     line_bufs=line_bufs,
                                     point_bufs=point_bufs,
                                     default_class_id=0)
     source = cfg.build(class_config, crs_transformer)
     return source.get_geojson(to_map_coords=to_map_coords)
Beispiel #7
0
    def test_compute(self):
        class_config = ClassConfig(names=['one', 'two'])
        class_config.update()
        class_config.ensure_null_class()

        gt_array = np.zeros((4, 4, 1), dtype=np.uint8)
        gt_array[2, 2, 0] = 1
        gt_array[0, 0, 0] = 2
        gt_raster = MockRasterSource([0], 1)
        gt_raster.set_raster(gt_array)
        gt_label_source = SemanticSegmentationLabelSource(
            raster_source=gt_raster)

        p_array = np.zeros((4, 4, 1), dtype=np.uint8)
        p_array[1, 1, 0] = 1
        p_raster = MockRasterSource([0], 1)
        p_raster.set_raster(p_array)
        p_label_source = SemanticSegmentationLabelSource(
            raster_source=p_raster)

        eval = SemanticSegmentationEvaluation(class_config)
        eval.compute(gt_label_source.get_labels(), p_label_source.get_labels())

        tp0 = 16 - 3  # 4*4 - 3 true positives for class 0
        fp0 = 1  # 1 false positive (2,2) and one don't care at (0,0)
        fn0 = 1  # one false negative (1,1)
        precision0 = float(tp0) / (tp0 + fp0)
        recall0 = float(tp0) / (tp0 + fn0)
        f10 = 2 * float(precision0 * recall0) / (precision0 + recall0)

        tp1 = 0  # 0 true positives for class 1
        fn1 = 1  # one false negative (2,2)
        precision1 = 0  # float(tp1) / (tp1 + fp1) where fp1 == 1
        recall1 = float(tp1) / (tp1 + fn1)
        f11 = None

        self.assertAlmostEqual(precision0,
                               eval.class_to_eval_item[0].precision)
        self.assertAlmostEqual(recall0, eval.class_to_eval_item[0].recall)
        self.assertAlmostEqual(f10, eval.class_to_eval_item[0].f1)

        self.assertEqual(precision1, eval.class_to_eval_item[1].precision)
        self.assertAlmostEqual(recall1, eval.class_to_eval_item[1].recall)
        self.assertAlmostEqual(f11, eval.class_to_eval_item[1].f1)

        avg_conf_mat = np.array([[0, 0, 0], [13., 1, 0], [1, 0, 0]])
        avg_recall = (14 / 15) * recall0 + (1 / 15) * recall1
        self.assertTrue(np.array_equal(avg_conf_mat, eval.avg_item.conf_mat))
        self.assertEqual(avg_recall, eval.avg_item.recall)
Beispiel #8
0
    def setUp(self):
        self.file_name = 'labels.json'
        self.tmp_dir = rv_config.get_tmp_dir()
        self.file_path = os.path.join(self.tmp_dir.name, self.file_name)

        self.crs_transformer = DoubleCRSTransformer()
        self.geojson = {
            'type':
            'FeatureCollection',
            'features': [{
                'type': 'Feature',
                'geometry': {
                    'type':
                    'Polygon',
                    'coordinates': [[[0., 0.], [0., 1.], [1., 1.], [1., 0.],
                                     [0., 0.]]]
                },
                'properties': {
                    'class_id': 0,
                    'score': 0.9
                }
            }, {
                'type': 'Feature',
                'geometry': {
                    'type':
                    'Polygon',
                    'coordinates': [[[1., 1.], [1., 2.], [2., 2.], [2., 1.],
                                     [1., 1.]]]
                },
                'properties': {
                    'score': 0.9,
                    'class_id': 1
                }
            }]
        }

        self.extent = Box.make_square(0, 0, 10)
        self.class_config = ClassConfig(names=['car', 'house'])
        json_to_file(self.geojson, self.file_path)
Beispiel #9
0
    def test_vector_compute(self):
        class_config = ClassConfig(names=['one', 'two'])
        class_config.update()
        class_config.ensure_null_class()

        gt_uri = data_file_path('2-gt-polygons.geojson')
        pred_uri = data_file_path('2-pred-polygons.geojson')

        eval = SemanticSegmentationEvaluation(class_config)
        eval.compute_vector(gt_uri, pred_uri, 'polygons', 0)

        # NOTE: The  two geojson files referenced  above contain three
        # unique geometries total, each  file contains two geometries,
        # and there is one geometry shared between the two.
        tp = 1.0
        fp = 1.0
        fn = 1.0
        precision = float(tp) / (tp + fp)
        recall = float(tp) / (tp + fn)

        self.assertAlmostEqual(precision, eval.class_to_eval_item[0].precision)
        self.assertAlmostEqual(recall, eval.class_to_eval_item[0].recall)
Beispiel #10
0
    def test_compute_ignore_class(self):
        class_config = ClassConfig(names=['one', 'two'])
        class_config.update()
        class_config.ensure_null_class()

        gt_array = np.zeros((4, 4, 1), dtype=np.uint8)
        gt_array[0, 0, 0] = 2
        gt_raster = MockRasterSource([0], 1)
        gt_raster.set_raster(gt_array)
        gt_label_source = SemanticSegmentationLabelSource(
            raster_source=gt_raster)

        pred_array = np.zeros((4, 4, 1), dtype=np.uint8)
        pred_array[0, 0, 0] = 1
        pred_raster = MockRasterSource([0], 1)
        pred_raster.set_raster(pred_array)
        pred_label_source = SemanticSegmentationLabelSource(
            raster_source=pred_raster)

        eval = SemanticSegmentationEvaluation(class_config)
        eval.compute(gt_label_source.get_labels(),
                     pred_label_source.get_labels())
        self.assertAlmostEqual(1.0, eval.class_to_eval_item[0].f1)
        self.assertAlmostEqual(1.0, eval.avg_item.f1)
Beispiel #11
0
def get_config(runner, root_uri, data_uri=None, full_train=False):
    def get_path(part):
        if full_train:
            return join(data_uri, part)
        else:
            return join(dirname(__file__), part)

    class_config = ClassConfig(names=['car', 'building'],
                               colors=['blue', 'red'])

    def make_scene(scene_id, img_path, label_path):
        raster_source = RasterioSourceConfig(channel_order=[0, 1, 2],
                                             uris=[img_path])
        label_source = ObjectDetectionLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=label_path,
                                                    default_class_id=None))
        return SceneConfig(id=scene_id,
                           raster_source=raster_source,
                           label_source=label_source)

    if full_train:
        model = ObjectDetectionModelConfig(backbone=Backbone.resnet18)
        solver = SolverConfig(lr=1e-4,
                              num_epochs=300,
                              batch_sz=8,
                              one_cycle=True,
                              sync_interval=300)
    else:
        pretrained_uri = (
            's3://raster-vision-lf-dev/integration_tests/object_detection/output/train/'
            'last-model.pth')
        model = ObjectDetectionModelConfig(backbone=Backbone.resnet18,
                                           init_weights=pretrained_uri)
        solver = SolverConfig(lr=1e-9,
                              num_epochs=1,
                              batch_sz=2,
                              one_cycle=True,
                              sync_interval=200)
    backend = PyTorchObjectDetectionConfig(model=model,
                                           solver=solver,
                                           log_tensorboard=False,
                                           run_tensorboard=False,
                                           augmentors=[])

    scenes = [
        make_scene('od_test', get_path('scene/image.tif'),
                   get_path('scene/labels.json')),
        make_scene('od_test-2', get_path('scene/image2.tif'),
                   get_path('scene/labels2.json'))
    ]
    dataset = DatasetConfig(class_config=class_config,
                            train_scenes=scenes,
                            validation_scenes=scenes)

    chip_options = ObjectDetectionChipOptions(neg_ratio=1.0, ioa_thresh=1.0)
    predict_options = ObjectDetectionPredictOptions(merge_thresh=0.1,
                                                    score_thresh=0.5)

    return ObjectDetectionConfig(root_uri=root_uri,
                                 dataset=dataset,
                                 backend=backend,
                                 train_chip_sz=300,
                                 predict_chip_sz=300,
                                 chip_options=chip_options,
                                 predict_options=predict_options)
Beispiel #12
0
 def make_class_config(self):
     return ClassConfig(names=['name', 'building'])
Beispiel #13
0
def get_config(runner, root_uri, data_uri=None, full_train=False):
    def get_path(part):
        if full_train:
            return join(data_uri, part)
        else:
            return join(dirname(__file__), part)

    class_config = ClassConfig(names=['red', 'green'], colors=['red', 'green'])

    def make_scene(id, img_path, label_path):
        raster_source = RasterioSourceConfig(channel_order=[0, 1, 2],
                                             uris=[img_path])
        label_source = SemanticSegmentationLabelSourceConfig(
            rgb_class_config=class_config,
            raster_source=RasterioSourceConfig(uris=[label_path]))
        label_store = SemanticSegmentationLabelStoreConfig(
            rgb=True,
            vector_output=[
                PolygonVectorOutputConfig(class_id=0),
                BuildingVectorOutputConfig(class_id=1)
            ])

        return SceneConfig(id=id,
                           raster_source=raster_source,
                           label_source=label_source,
                           label_store=label_store)

    if full_train:
        model = SemanticSegmentationModelConfig(backbone=Backbone.resnet50)
        solver = SolverConfig(lr=1e-4,
                              num_epochs=300,
                              batch_sz=8,
                              one_cycle=True,
                              sync_interval=300)
    else:
        pretrained_uri = (
            's3://raster-vision-lf-dev/integration_tests/semantic_segmentation/output/'
            'train/last-model.pth')
        model = SemanticSegmentationModelConfig(backbone=Backbone.resnet50,
                                                init_weights=pretrained_uri)
        solver = SolverConfig(lr=1e-9,
                              num_epochs=1,
                              batch_sz=2,
                              one_cycle=True,
                              sync_interval=200)
    backend = PyTorchSemanticSegmentationConfig(model=model,
                                                solver=solver,
                                                log_tensorboard=False,
                                                run_tensorboard=False,
                                                augmentors=[])

    scenes = [
        make_scene('test-scene', get_path('scene/image.tif'),
                   get_path('scene/labels.tif')),
        make_scene('test-scene2', get_path('scene/image2.tif'),
                   get_path('scene/labels2.tif'))
    ]
    dataset = DatasetConfig(class_config=class_config,
                            train_scenes=scenes,
                            validation_scenes=scenes)

    chip_options = SemanticSegmentationChipOptions(
        window_method=SemanticSegmentationWindowMethod.sliding, stride=300)

    return SemanticSegmentationConfig(root_uri=root_uri,
                                      dataset=dataset,
                                      backend=backend,
                                      train_chip_sz=300,
                                      predict_chip_sz=300,
                                      chip_options=chip_options)
Beispiel #14
0
def get_config(runner, root_uri, data_uri=None, full_train=False):
    def get_path(part):
        if full_train:
            return join(data_uri, part)
        else:
            return join(dirname(__file__), part)

    class_config = ClassConfig(names=['car', 'building', 'background'],
                               colors=['red', 'blue', 'black'])

    def make_scene(img_path, label_path):
        id = basename(img_path)
        label_source = ChipClassificationLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=label_path,
                                                    default_class_id=None,
                                                    ignore_crs_field=True),
            ioa_thresh=0.5,
            use_intersection_over_cell=False,
            pick_min_class_id=True,
            background_class_id=2,
            infer_cells=True)

        raster_source = RasterioSourceConfig(
            channel_order=[0, 1, 2],
            uris=[img_path],
            transformers=[StatsTransformerConfig()])

        return SceneConfig(id=id,
                           raster_source=raster_source,
                           label_source=label_source)

    scenes = [
        make_scene(get_path('scene/image.tif'), get_path('scene/labels.json')),
        make_scene(get_path('scene/image2.tif'),
                   get_path('scene/labels2.json'))
    ]
    dataset = DatasetConfig(class_config=class_config,
                            train_scenes=scenes,
                            validation_scenes=scenes)

    if full_train:
        model = ClassificationModelConfig(backbone=Backbone.resnet18)
        solver = SolverConfig(lr=1e-4,
                              num_epochs=300,
                              batch_sz=8,
                              one_cycle=True,
                              sync_interval=300)
    else:
        pretrained_uri = (
            's3://raster-vision-lf-dev/integration_tests/chip_classification/output/'
            'train/last-model.pth')
        model = ClassificationModelConfig(backbone=Backbone.resnet18,
                                          init_weights=pretrained_uri)
        solver = SolverConfig(lr=1e-9,
                              num_epochs=1,
                              batch_sz=2,
                              one_cycle=True,
                              sync_interval=200)
    backend = PyTorchChipClassificationConfig(model=model,
                                              solver=solver,
                                              log_tensorboard=False,
                                              run_tensorboard=False,
                                              augmentors=[])

    config = ChipClassificationConfig(root_uri=root_uri,
                                      dataset=dataset,
                                      backend=backend,
                                      train_chip_sz=200,
                                      predict_chip_sz=200)

    return config
    def setUp(self):
        self.tmp_dir = rv_config.get_tmp_dir()

        self.class_config = ClassConfig(names=['one', 'two'])
        self.class_config.update()
        self.class_config.ensure_null_class()
class TestSemanticSegmentationEvaluator(unittest.TestCase):
    def setUp(self):
        self.tmp_dir = rv_config.get_tmp_dir()

        self.class_config = ClassConfig(names=['one', 'two'])
        self.class_config.update()
        self.class_config.ensure_null_class()

    def tearDown(self):
        self.tmp_dir.cleanup()

    def get_scene(self, class_id):
        # Make scene where ground truth is all set to class_id
        # and predictions are set to half 0's and half 1's
        scene_id = str(class_id)
        rs = MockRasterSource(channel_order=[0, 1, 2], num_channels=3)
        rs.set_raster(np.zeros((10, 10, 3)))

        gt_rs = MockRasterSource(channel_order=[0], num_channels=1)
        gt_arr = np.full((10, 10, 1), class_id)
        gt_rs.set_raster(gt_arr)
        gt_ls = SemanticSegmentationLabelSource(raster_source=gt_rs)

        pred_rs = MockRasterSource(channel_order=[0], num_channels=1)
        pred_arr = np.zeros((10, 10, 1))
        pred_arr[5:10, :, :] = 1
        pred_rs.set_raster(pred_arr)
        pred_ls = SemanticSegmentationLabelSource(raster_source=pred_rs)

        return Scene(scene_id, rs, gt_ls, pred_ls)

    def test_evaluator(self):
        output_uri = join(self.tmp_dir.name, 'out.json')
        scenes = [self.get_scene(0), self.get_scene(1)]
        evaluator = SemanticSegmentationEvaluator(self.class_config,
                                                  output_uri, None)
        evaluator.process(scenes, self.tmp_dir.name)
        eval_json = file_to_json(output_uri)
        exp_eval_json = file_to_json(data_file_path('expected-eval.json'))
        self.assertDictEqual(eval_json, exp_eval_json)

    def get_vector_scene(self, class_id, use_aoi=False):
        gt_uri = data_file_path('{}-gt-polygons.geojson'.format(class_id))
        pred_uri = data_file_path('{}-pred-polygons.geojson'.format(class_id))

        scene_id = str(class_id)
        rs = MockRasterSource(channel_order=[0, 1, 3], num_channels=3)
        rs.set_raster(np.zeros((10, 10, 3)))

        crs_transformer = IdentityCRSTransformer()
        extent = Box.make_square(0, 0, 360)

        config = RasterizedSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=gt_uri,
                                                    default_class_id=0),
            rasterizer_config=RasterizerConfig(background_class_id=1))
        gt_rs = config.build(self.class_config, crs_transformer, extent)
        gt_ls = SemanticSegmentationLabelSource(raster_source=gt_rs)

        config = RasterizedSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=pred_uri,
                                                    default_class_id=0),
            rasterizer_config=RasterizerConfig(background_class_id=1))
        pred_rs = config.build(self.class_config, crs_transformer, extent)
        pred_ls = SemanticSegmentationLabelSource(raster_source=pred_rs)
        pred_ls.vector_output = [
            PolygonVectorOutputConfig(uri=pred_uri,
                                      denoise=0,
                                      class_id=class_id)
        ]

        if use_aoi:
            aoi_uri = data_file_path('{}-aoi.geojson'.format(class_id))
            aoi_geojson = file_to_json(aoi_uri)
            aoi_polygons = [shape(aoi_geojson['features'][0]['geometry'])]
            return Scene(scene_id, rs, gt_ls, pred_ls, aoi_polygons)

        return Scene(scene_id, rs, gt_ls, pred_ls)

    def test_vector_evaluator(self):
        output_uri = join(self.tmp_dir.name, 'raster-out.json')
        vector_output_uri = join(self.tmp_dir.name, 'vector-out.json')
        scenes = [self.get_vector_scene(0), self.get_vector_scene(1)]
        evaluator = SemanticSegmentationEvaluator(self.class_config,
                                                  output_uri,
                                                  vector_output_uri)
        evaluator.process(scenes, self.tmp_dir.name)
        vector_eval_json = file_to_json(vector_output_uri)
        exp_vector_eval_json = file_to_json(
            data_file_path('expected-vector-eval.json'))

        # NOTE:  The precision  and recall  values found  in the  file
        # `expected-vector-eval.json`  are equal to fractions of  the
        # form (n-1)/n for  n <= 7 which  can be seen to  be (and have
        # been manually verified to be) correct.
        self.assertDictEqual(vector_eval_json, exp_vector_eval_json)

    def test_vector_evaluator_with_aoi(self):
        output_uri = join(self.tmp_dir.name, 'raster-out.json')
        vector_output_uri = join(self.tmp_dir.name, 'vector-out.json')
        scenes = [self.get_vector_scene(0, use_aoi=True)]
        evaluator = SemanticSegmentationEvaluator(self.class_config,
                                                  output_uri,
                                                  vector_output_uri)
        evaluator.process(scenes, self.tmp_dir.name)
        vector_eval_json = file_to_json(vector_output_uri)
        exp_vector_eval_json = file_to_json(
            data_file_path('expected-vector-eval-with-aoi.json'))

        # NOTE:  The precision  and recall  values found  in the  file
        # `expected-vector-eval.json`  are equal to fractions of  the
        # form (n-1)/n for  n <= 7 which  can be seen to  be (and have
        # been manually verified to be) correct.
        self.assertDictEqual(vector_eval_json, exp_vector_eval_json)