def test_get_overlapping(self): window = Box.make_square(0, 0, 2.01) labels = ObjectDetectionLabels.get_overlapping(self.labels, window) labels.assert_equal(self.labels) window = Box.make_square(0, 0, 3) labels = ObjectDetectionLabels.get_overlapping(self.labels, window, ioa_thresh=0.5) 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) window = Box.make_square(0, 0, 3) labels = ObjectDetectionLabels.get_overlapping(self.labels, window, ioa_thresh=0.1, clip=True) expected_npboxes = np.array([ [0., 0., 2., 2.], [2., 2., 3., 3.], ]) expected_labels = ObjectDetectionLabels(expected_npboxes, self.class_ids, scores=self.scores) labels.assert_equal(expected_labels)
def setUp(self): self.windows = [Box.make_square(0, 0, 10), Box.make_square(0, 10, 10)] self.label_arr0 = np.random.choice([0, 1], (10, 10)) self.label_arr1 = np.random.choice([0, 1], (10, 10)) self.labels = SemanticSegmentationLabels() self.labels.set_label_arr(self.windows[0], self.label_arr0) self.labels.set_label_arr(self.windows[1], self.label_arr1)
def setUp(self): self.labels = ChipClassificationLabels() self.cell1 = Box.make_square(0, 0, 2) self.class_id1 = 1 self.labels.set_cell(self.cell1, self.class_id1) self.cell2 = Box.make_square(0, 2, 2) self.class_id2 = 2 self.labels.set_cell(self.cell2, self.class_id2)
def test_make_buffer(self): buffer_size = 1 max_extent = Box.make_square(0, 0, 3) buffer_box = Box(0, 0, 3, 3) output_buffer_box = self.box.make_buffer(buffer_size, max_extent) self.assertEqual(output_buffer_box, buffer_box) buffer_size = 0.5 max_extent = Box.make_square(0, 0, 5) buffer_box = Box(0, 0, 3, 5) output_buffer_box = self.box.make_buffer(buffer_size, max_extent) self.assertEqual(output_buffer_box, buffer_box)
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)
def test_filter_by_aoi(self): aois = [Box.make_square(0, 0, 2).to_shapely()] filt_labels = self.labels.filter_by_aoi(aois) npboxes = np.array([[0., 0., 2., 2.]]) class_ids = np.array([0]) scores = np.array([0.9]) exp_labels = ObjectDetectionLabels(npboxes, class_ids, scores=scores) self.assertEqual(filt_labels, exp_labels) aois = [Box.make_square(4, 4, 2).to_shapely()] filt_labels = self.labels.filter_by_aoi(aois) exp_labels = ObjectDetectionLabels.make_empty() self.assertEqual(filt_labels, exp_labels)
def test_get_windows(self): extent = Box(0, 0, 100, 100) windows = list(extent.get_windows(10, 10)) self.assertEqual(len(windows), 100) extent = Box(0, 0, 100, 100) windows = list(extent.get_windows(10, 5)) self.assertEqual(len(windows), 400) extent = Box(0, 0, 20, 20) windows = set( [window.tuple_format() for window in extent.get_windows(10, 10)]) expected_windows = [ Box.make_square(0, 0, 10), Box.make_square(10, 0, 10), Box.make_square(0, 10, 10), Box.make_square(10, 10, 10) ] expected_windows = set( [window.tuple_format() for window in expected_windows]) self.assertSetEqual(windows, expected_windows) extent = Box(10, 10, 20, 20) windows = set( [window.tuple_format() for window in extent.get_windows(6, 6)]) expected_windows = [ Box.make_square(10, 10, 6), Box.make_square(10, 16, 6), Box.make_square(16, 10, 6), Box.make_square(16, 16, 6) ] expected_windows = set( [window.tuple_format() for window in expected_windows]) self.assertSetEqual(windows, expected_windows)
def test_filter_by_aoi(self): aois = [Box.make_square(0, 0, 2).to_shapely()] filt_labels = self.labels.filter_by_aoi(aois) exp_labels = ChipClassificationLabels() cell1 = Box.make_square(0, 0, 2) class_id1 = 1 exp_labels.set_cell(cell1, class_id1) self.assertEqual(filt_labels, exp_labels) aois = [Box.make_square(4, 4, 2).to_shapely()] filt_labels = self.labels.filter_by_aoi(aois) exp_labels = ChipClassificationLabels() self.assertEqual(filt_labels, exp_labels)
def test_make_eroded(self): max_extent = Box.make_square(0, 0, 10) box = Box(1, 1, 3, 4) buffer_size = erosion_size = 1 eroded_box = box.make_buffer(buffer_size, max_extent) \ .make_eroded(erosion_size) self.assertEqual(eroded_box, box)
def __init__(self, uris, raster_transformers, tmp_dir, channel_order=None, x_shift=0.0, y_shift=0.0): """Constructor. This RasterSource can read any file that can be opened by Rasterio/GDAL including georeferenced formats such as GeoTIFF and non-georeferenced formats such as JPG. See https://www.gdal.org/formats_list.html for more details. If channel_order is None, then use non-alpha channels. This also sets any masked or NODATA pixel values to be zeros. Args: channel_order: list of indices of channels to extract from raw imagery """ self.uris = uris self.tmp_dir = tmp_dir self.image_tmp_dir = None self.image_dataset = None self.x_shift = x_shift self.y_shift = y_shift num_channels = None # Activate in order to get information out of the raster with self.activate(): num_channels = self.image_dataset.count if channel_order is None: colorinterp = self.image_dataset.colorinterp if colorinterp: channel_order = [ i for i, color_interp in enumerate(colorinterp) if color_interp != ColorInterp.alpha ] else: channel_order = list(range(0, num_channels)) self.validate_channel_order(channel_order, num_channels) mask_flags = self.image_dataset.mask_flag_enums self.is_masked = any( [m for m in mask_flags if m != MaskFlags.all_valid]) self.height = self.image_dataset.height self.width = self.image_dataset.width # Get 1x1 chip and apply raster transformers to test dtype. test_chip = self.get_raw_chip(Box.make_square(0, 0, 1)) test_chip = test_chip[:, :, channel_order] for transformer in raster_transformers: test_chip = transformer.transform(test_chip, channel_order) self.dtype = test_chip.dtype self._set_crs_transformer() super().__init__(channel_order, num_channels, raster_transformers)
def test_global_to_local(self): global_npboxes = np.array([[10., 10., 12., 12.], [12., 12., 14., 14.]]) window = Box.make_square(10, 10, 10) local_npboxes = ObjectDetectionLabels.global_to_local( global_npboxes, window) expected_local_npboxes = np.array([[0., 0., 2., 2.], [2., 2., 4., 4.]]) np.testing.assert_array_equal(local_npboxes, expected_local_npboxes)
def test_extend(self): labels = ChipClassificationLabels() cell3 = Box.make_square(0, 4, 2) class_id3 = 1 labels.set_cell(cell3, class_id3) self.labels.extend(labels) cells = self.labels.get_cells() self.assertEqual(len(cells), 3) self.assertTrue(cell3 in cells)
def test_get_cell(self): cell = Box.make_square(0, 2, 3) class_id = self.labels.get_cell_class_id(cell) self.assertEqual(class_id, None) class_id = self.labels.get_cell_class_id(self.cell1) self.assertEqual(class_id, self.class_id1) class_id = self.labels.get_cell_class_id(self.cell2) self.assertEqual(class_id, self.class_id2)
def test_get_with_aoi(self): null_class_id = 2 aoi_polygons = [Box.make_square(5, 15, 2).to_shapely()] exp_label_arr = np.full(self.label_arr1.shape, null_class_id) exp_label_arr[5:7, 5:7] = self.label_arr1[5:7, 5:7] labels = self.labels.filter_by_aoi(aoi_polygons, null_class_id) label_arr = labels.get_label_arr(self.windows[1]) np.testing.assert_array_equal(label_arr, exp_label_arr) self.assertEqual(1, len(labels.window_to_label_arr))
def test_infer_cell3(self): # Only box 2 is in cell, but IOA isn't high enough. cell = Box.make_square(3, 3, 3) ioa_thresh = 0.5 use_intersection_over_cell = False background_class_id = None pick_min_class_id = False class_id = infer_cell(cell, self.str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) self.assertEqual(class_id, None)
def test_infer_cell6(self): # No boxes overlap enough, use background_class_id cell = Box.make_square(0, 0, 10) ioa_thresh = 0.5 use_intersection_over_cell = True background_class_id = self.background_class_id pick_min_class_id = False class_id = infer_cell(cell, self.str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) self.assertEqual(class_id, self.background_class_id)
def test_infer_cell2(self): # More of box 2 is in cell. cell = Box.make_square(1, 1, 3) ioa_thresh = 0.5 use_intersection_over_cell = False background_class_id = None pick_min_class_id = False class_id = infer_cell(cell, self.str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) self.assertEqual(class_id, self.class_id2)
def test_infer_cell7(self): # Cell doesn't overlap with any boxes. cell = Box.make_square(10, 10, 1) ioa_thresh = 0.5 use_intersection_over_cell = True background_class_id = None pick_min_class_id = False class_id = infer_cell(cell, self.str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) self.assertEqual(class_id, None)
def test_infer_cell5(self): # More of box1 in cell, using intersection_over_cell with the # IOA high enough. cell = Box.make_square(0, 0, 3) ioa_thresh = 0.4 use_intersection_over_cell = True background_class_id = None pick_min_class_id = False class_id = infer_cell(cell, self.str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) self.assertEqual(class_id, self.class_id1)
def test_infer_cell4(self): # Both boxes inside cell, but using intersection_over_cell, # the IOA isn't high enough. cell = Box.make_square(0, 0, 10) ioa_thresh = 0.5 use_intersection_over_cell = True background_class_id = None pick_min_class_id = False class_id = infer_cell(cell, self.str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) self.assertEqual(class_id, None)
def test_infer_cell8(self): # box2 overlaps more than box1, but using pick_min_class_id, so # picks box1. cell = Box.make_square(1, 1, 3) ioa_thresh = 0.5 use_intersection_over_cell = False background_class_id = None pick_min_class_id = True class_id = infer_cell(cell, self.str_tree, ioa_thresh, use_intersection_over_cell, background_class_id, pick_min_class_id) self.assertEqual(class_id, self.class_id2)
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)
def test_get_labels(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) 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, self.class_id2)
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)
def test_make_square(self): square = Box(0, 0, 10, 10) output_square = Box.make_square(0, 0, 10) self.assertEqual(output_square, square) self.assertEqual(output_square.get_width(), output_square.get_height())