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)
    def test_read_with_extent(self):
        # Extent only includes the first box.
        extent = Box.make_square(0, 0, 3)
        config = ObjectDetectionLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(
                uri=self.file_path, default_class_id=None))
        source = config.build(self.class_config, self.crs_transformer, extent,
                              self.tmp_dir.name)
        labels = source.get_labels()

        npboxes = np.array([[0., 0., 2., 2.]])
        class_ids = np.array([0])
        scores = np.array([0.9])
        expected_labels = ObjectDetectionLabels(
            npboxes, class_ids, scores=scores)
        labels.assert_equal(expected_labels)

        # Extent includes both boxes, but clips the second.
        extent = Box.make_square(0, 0, 3.9)
        config = ObjectDetectionLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(
                uri=self.file_path, default_class_id=None))
        source = config.build(self.class_config, self.crs_transformer, extent,
                              self.tmp_dir.name)
        labels = source.get_labels()

        npboxes = np.array([[0., 0., 2., 2.], [2., 2., 3.9, 3.9]])
        class_ids = np.array([0, 1])
        scores = np.array([0.9, 0.9])
        expected_labels = ObjectDetectionLabels(
            npboxes, class_ids, scores=scores)
        labels.assert_equal(expected_labels)
    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 hrefs_to_sceneconfig(
        imagery: str,
        labels: Optional[str],
        name: str,
        class_id_filter_dict: Dict[int, str],
        extent_crop: Optional[CropOffsets] = None) -> SceneConfig:

    transformers = [CastTransformerConfig(to_dtype='float16')]
    image_source = RasterioSourceConfig(
        channel_order=list(range(224)),
        uris=[imagery],
        allow_streaming=True,
        transformers=transformers,
        extent_crop=extent_crop,
    )

    label_vector_source = GeoJSONVectorSourceConfig(
        uri=labels,
        class_id_to_filter=class_id_filter_dict,
        default_class_id=0xff)
    label_raster_source = RasterizedSourceConfig(
        vector_source=label_vector_source,
        rasterizer_config=RasterizerConfig(background_class_id=0,
                                           all_touched=True))
    label_source = SemanticSegmentationLabelSourceConfig(
        raster_source=label_raster_source)

    return SceneConfig(id=name,
                       raster_source=image_source,
                       label_source=label_source)
 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 #6
0
 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)
Beispiel #7
0
 def test_using_null_class_bufs(self):
     vs = GeoJSONVectorSourceConfig(uri=self.uri,
                                    default_class_id=None,
                                    line_bufs={0: None})
     with self.assertRaises(ConfigError):
         config = RasterizedSourceConfig(
             vector_source=vs,
             rasterizer_config=RasterizerConfig(
                 background_class_id=self.background_class_id))
         config.validate_config()
Beispiel #8
0
    def build_source(self, geojson, all_touched=False):
        json_to_file(geojson, self.uri)

        config = RasterizedSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=self.uri,
                                                    default_class_id=None),
            rasterizer_config=RasterizerConfig(
                background_class_id=self.background_class_id,
                all_touched=all_touched))
        source = config.build(self.class_config, self.crs_transformer,
                              self.extent)
        return source
    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(gt_rs, self.null_class_id)

        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(pred_rs, self.null_class_id)
        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_read_without_extent(self):
        config = ObjectDetectionLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(
                uri=self.file_path, default_class_id=None))
        extent = None
        source = config.build(self.class_config, self.crs_transformer, extent,
                              self.tmp_dir.name)
        labels = source.get_labels()

        npboxes = np.array([[0., 0., 2., 2.], [2., 2., 4., 4.]])
        class_ids = np.array([0, 1])
        scores = np.array([0.9, 0.9])
        expected_labels = ObjectDetectionLabels(
            npboxes, class_ids, scores=scores)
        labels.assert_equal(expected_labels)
    def test_getitem(self):
        # Extent contains both boxes.
        extent = Box.make_square(0, 0, 8)

        config = ChipClassificationLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=self.uri,
                                                    default_class_id=None))
        source = config.build(self.class_config, self.crs_transformer, extent,
                              self.tmp_dir.name)
        labels = source.get_labels()

        cells = labels.get_cells()
        self.assertEqual(len(cells), 2)
        self.assertEqual(source[cells[0]], self.class_id1)
        self.assertEqual(source[cells[1]], self.class_id2)
Beispiel #12
0
    def test_get_labels_small_extent(self):
        # Extent only has enough of first box in it.
        extent = Box.make_square(0, 0, 2)

        config = ChipClassificationLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=self.uri,
                                                    default_class_id=None))
        source = config.build(self.class_config, self.crs_transformer, extent,
                              self.tmp_dir.name)
        labels = source.get_labels()

        cells = labels.get_cells()
        self.assertEqual(len(cells), 1)
        class_id = labels.get_cell_class_id(self.box1)
        self.assertEqual(class_id, self.class_id1)
        class_id = labels.get_cell_class_id(self.box2)
        self.assertEqual(class_id, None)
Beispiel #13
0
    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)
Beispiel #14
0
    def test_get_labels_inferred(self):
        extent = Box.make_square(0, 0, 8)

        config = ChipClassificationLabelSourceConfig(
            vector_source=GeoJSONVectorSourceConfig(uri=self.uri,
                                                    default_class_id=None),
            ioa_thresh=0.5,
            use_intersection_over_cell=False,
            pick_min_class_id=False,
            background_class_id=self.background_class_id,
            infer_cells=True,
            cell_sz=4)
        source = config.build(self.class_config, self.crs_transformer, extent,
                              self.tmp_dir.name)
        labels = source.get_labels()
        cells = labels.get_cells()

        self.assertEqual(len(cells), 4)
        self.assertEqual(labels.get_cell_class_id(self.box1), self.class_id1)
        self.assertEqual(labels.get_cell_class_id(self.box2), self.class_id2)
        self.assertEqual(labels.get_cell_class_id(Box.make_square(0, 4, 4)),
                         self.background_class_id)
        self.assertEqual(labels.get_cell_class_id(Box.make_square(4, 0, 4)),
                         self.background_class_id)
Beispiel #15
0
def save_image_crop(image_uri,
                    image_crop_uri,
                    label_uri=None,
                    label_crop_uri=None,
                    size=600,
                    min_features=10,
                    vector_labels=True,
                    class_config=None):
    """Save a crop of an image to use for testing.

    If label_uri is set, the crop needs to cover >= min_features.

    Args:
        image_uri: URI of original image
        image_crop_uri: URI of cropped image to save
        label_uri: optional URI of label file
        label_crop_uri: optional URI of cropped labels to save
        size: height and width of crop

    Raises:
        ValueError if cannot find a crop satisfying min_features constraint.
    """
    if not file_exists(image_crop_uri):
        print('Saving test crop to {}...'.format(image_crop_uri))
        old_environ = os.environ.copy()
        try:
            request_payer = S3FileSystem.get_request_payer()
            if request_payer == 'requester':
                os.environ['AWS_REQUEST_PAYER'] = request_payer
            im_dataset = rasterio.open(image_uri)
            h, w = im_dataset.height, im_dataset.width

            extent = Box(0, 0, h, w)
            windows = extent.get_windows(size, size)
            if label_uri and vector_labels:
                crs_transformer = RasterioCRSTransformer.from_dataset(
                    im_dataset)
                geojson_vs_config = GeoJSONVectorSourceConfig(
                    uri=label_uri, default_class_id=0, ignore_crs_field=True)
                vs = geojson_vs_config.build(class_config, crs_transformer)
                geojson = vs.get_geojson()
                geoms = []
                for f in geojson['features']:
                    g = shape(f['geometry'])
                    geoms.append(g)
                tree = STRtree(geoms)

            def p2m(x, y, z=None):
                return crs_transformer.pixel_to_map((x, y))

            for w in windows:
                use_window = True
                if label_uri and vector_labels:
                    w_polys = tree.query(w.to_shapely())
                    use_window = len(w_polys) >= min_features
                    if use_window and label_crop_uri is not None:
                        print('Saving test crop labels to {}...'.format(
                            label_crop_uri))

                        label_crop_features = [
                            mapping(transform(p2m, wp)) for wp in w_polys
                        ]
                        label_crop_json = {
                            'type':
                            'FeatureCollection',
                            'features': [{
                                'geometry': f
                            } for f in label_crop_features]
                        }
                        json_to_file(label_crop_json, label_crop_uri)

                if use_window:
                    crop_image(image_uri, w, image_crop_uri)

                    if not vector_labels and label_uri and label_crop_uri:
                        crop_image(label_uri, w, label_crop_uri)

                    break

            if not use_window:
                raise ValueError('Could not find a good crop.')
        finally:
            os.environ.clear()
            os.environ.update(old_environ)