def worker(tile): x, y, z = list(map(str, tile)) if args.masks and args.labels: label = np.array(Image.open(os.path.join(args.labels, z, x, "{}.png".format(y)))) mask = np.array(Image.open(os.path.join(args.masks, z, x, "{}.png".format(y)))) assert label.shape == mask.shape, "Inconsistent tiles (size or dimensions)" try: dist, fg_ratio, qod = compare(torch.as_tensor(label, device="cpu"), torch.as_tensor(mask, device="cpu")) except: progress.update() return False, tile if not args.minimum_fg <= fg_ratio <= args.maximum_fg or not args.minimum_qod <= qod <= args.maximum_qod: progress.update() return True, tile tiles_compare.append(tile) if args.mode == "side": for i, root in enumerate(args.images): img = tile_image_from_file(tile_from_xyz(root, x, y, z)[1]) if i == 0: side = np.zeros((img.shape[0], img.shape[1] * len(args.images), 3)) side = np.swapaxes(side, 0, 1) if args.vertical else side image_shape = img.shape else: assert image_shape[0:2] == img.shape[0:2], "Unconsistent image size to compare" if args.vertical: side[i * image_shape[0] : (i + 1) * image_shape[0], :, :] = img else: side[:, i * image_shape[0] : (i + 1) * image_shape[0], :] = img tile_image_to_file(args.out, tile, np.uint8(side)) elif args.mode == "stack": for i, root in enumerate(args.images): tile_image = tile_image_from_file(tile_from_xyz(root, x, y, z)[1]) if i == 0: image_shape = tile_image.shape[0:2] stack = tile_image / len(args.images) else: assert image_shape == tile_image.shape[0:2], "Unconsistent image size to compare" stack = stack + (tile_image / len(args.images)) tile_image_to_file(args.out, tile, np.uint8(stack)) elif args.mode == "list": tiles_list.append([tile, fg_ratio, qod]) progress.update() return True, tile
def worker(tile_key): if len(tiles_map[tile_key]) == 1: return image = np.zeros((width, height, bands), np.uint8) x, y, z = map(int, tile_key) for i in range(len(tiles_map[tile_key])): root = os.path.join(splits_path, str(i)) _, path = tile_from_xyz(root, x, y, z) if not args.label: split = tile_image_from_file(path) if args.label: split = tile_label_from_file(path) split = split.reshape((width, height, 1)) # H,W -> H,W,C assert image.shape == split.shape image[np.where(image == 0)] += split[np.where(image == 0)] if not args.label and is_nodata(image, args.nodata, args.nodata_threshold, args.keep_borders): progress.update() return tile = mercantile.Tile(x=x, y=y, z=z) if not args.label: tile_image_to_file(args.out, tile, image) if args.label: tile_label_to_file(args.out, tile, palette, image) progress.update() return tile
def __getitem__(self, i): tile, path = self.tiles[i] if self.mode == "mask": image = np.array(Image.open(path).convert("P")) elif self.mode == "image": image = tile_image_from_file(path) if self.transform is not None: image = self.transform(image) return image, tile
def worker(tile_key, nodata): if len(tiles_map[tile_key]) == 1: return image = np.zeros((args.ts, args.ts, bands), np.uint8) x, y, z = map(int, tile_key) for i in range(len(tiles_map[tile_key])): root = os.path.join(splits_path, str(i)) _, path = tile_from_xyz(root, x, y, z) if not args.label: split = tile_image_from_file(path) if args.label: split = tile_label_from_file(path) split = split.reshape( (args.ts, args.ts, 1)) # H,W -> H,W,C assert image.shape == split.shape image[:, :, :] += split[:, :, :] if not args.label and skip_nodata(image, nodata["border"], nodata["value"], nodata["threshold"]): progress.update() return tile = mercantile.Tile(x=x, y=y, z=z) if not args.label: ret = tile_image_to_file(args.out, tile, image) if args.label: ret = tile_label_to_file(args.out, tile, palette, image) if not ret: sys.exit("Error: Unable to write tile {}.".format( str(tile_key))) progress.update() return tile
def worker(tile_key): if len(tiles_map[tile_key]) == 1: return image = np.zeros((args.ts, args.ts, bands), np.uint8) x, y, z = map(int, tile_key) for i in range(len(tiles_map[tile_key])): root = os.path.join(splits_path, str(i)) _, path = tile_from_xyz(root, x, y, z) if not args.label: split = tile_image_from_file(path) if args.label: split = tile_label_from_file(path) split = split.reshape( (args.ts, args.ts, 1)) # H,W -> H,W,C assert image.shape == split.shape image[np.where(image == 0)] += split[np.where(image == 0)] if not args.label and is_nodata(image, threshold=args.nodata_threshold): progress.update() return tile = mercantile.Tile(x=x, y=y, z=z) if not args.label: ret = tile_image_to_file(args.out, tile, image) if args.label: ret = tile_label_to_file(args.out, tile, palette, image) assert ret, "Unable to write tile {} from raster {}.".format( str(tile_key)) progress.update() return tile
def __getitem__(self, i): tile = None mask = None image = None for channel in self.config["channels"]: image_channel = None bands = None if not channel["bands"] else channel["bands"] if tile is None: tile, path = self.tiles[channel["name"]][i] else: assert tile == self.tiles[ channel["name"]][i][0], "Dataset channel inconsistency" tile, path = self.tiles[channel["name"]][i] image_channel = tile_image_from_file(path, bands) assert image_channel is not None, "Dataset channel {} not retrieved: {}".format( channel["name"], path) image = np.concatenate( (image, image_channel), axis=2) if image is not None else image_channel if self.mode == "train": assert tile == self.tiles["labels"][i][ 0], "Dataset mask inconsistency" mask = tile_label_from_file(self.tiles["labels"][i][1]) assert mask is not None, "Dataset mask not retrieved" image, mask = to_normalized_tensor(self.config, self.shape_in[1:3], self.mode, image, mask) return image, mask, tile if self.mode == "predict": image = to_normalized_tensor(self.config, self.shape_in[1:3], self.mode, image) return image, torch.IntTensor([tile.x, tile.y, tile.z])
def main(args): if not args.masks or not args.labels or not args.config: if args.mode == "list": sys.exit("Parameters masks, labels and config, are all mandatories in list mode.") if args.minimum_fg > 0 or args.maximum_fg < 100 or args.minimum_qod > 0 or args.maximum_qod < 100: sys.exit("Parameters masks, labels and config, are all mandatories in QoD filtering.") if args.images: tiles = [tile for tile, _ in tiles_from_slippy_map(args.images[0])] for image in args.images[1:]: assert sorted(tiles) == sorted([tile for tile, _ in tiles_from_slippy_map(image)]), "inconsistent coverages" if args.labels and args.masks: tiles_masks = [tile for tile, _ in tiles_from_slippy_map(args.masks)] tiles_labels = [tile for tile, _ in tiles_from_slippy_map(args.labels)] if args.images: assert sorted(tiles) == sorted(tiles_masks) == sorted(tiles_labels), "inconsistent coverages" else: assert sorted(tiles_masks) == sorted(tiles_labels), "inconsistent coverages" tiles = tiles_masks if args.mode == "list": out = open(args.out, mode="w") if args.geojson: out.write('{"type":"FeatureCollection","features":[') first = True tiles_compare = [] for tile in tqdm(list(tiles), desc="Compare", unit="tile", ascii=True): x, y, z = list(map(str, tile)) if args.masks and args.labels and args.config: titles = [classe["title"] for classe in load_config(args.config)["classes"]] dist, fg_ratio, qod = compare(args.masks, args.labels, tile, titles) if not args.minimum_fg <= fg_ratio <= args.maximum_fg or not args.minimum_qod <= qod <= args.maximum_qod: continue tiles_compare.append(tile) if args.mode == "side": for i, root in enumerate(args.images): img = tile_image_from_file(tile_from_slippy_map(root, x, y, z)[1]) if i == 0: side = np.zeros((img.shape[0], img.shape[1] * len(args.images), 3)) side = np.swapaxes(side, 0, 1) if args.vertical else side image_shape = img.shape else: assert image_shape == img.shape, "Unconsistent image size to compare" if args.vertical: side[i * image_shape[0] : (i + 1) * image_shape[0], :, :] = img else: side[:, i * image_shape[0] : (i + 1) * image_shape[0], :] = img os.makedirs(os.path.join(args.out, z, x), exist_ok=True) cv2.imwrite(os.path.join(args.out, str(z), str(x), "{}.{}").format(y, args.format), np.uint8(side)) elif args.mode == "stack": for i, root in enumerate(args.images): img = tile_image_from_file(tile_from_slippy_map(root, x, y, z)[1]) if i == 0: image_shape = img.shape[0:2] stack = img / len(args.images) else: assert image_shape == img.shape[0:2], "Unconsistent image size to compare" stack = stack + (img / len(args.images)) os.makedirs(os.path.join(args.out, str(z), str(x)), exist_ok=True) cv2.imwrite(os.path.join(args.out, str(z), str(x), "{}.{}").format(y, args.format), np.uint8(stack)) elif args.mode == "list": if args.geojson: prop = '"properties":{{"x":{},"y":{},"z":{},"fg":{:.1f},"qod":{:.1f}}}'.format(x, y, z, fg_ratio, qod) geom = '"geometry":{}'.format(json.dumps(feature(tile, precision=6)["geometry"])) out.write('{}{{"type":"Feature",{},{}}}'.format("," if not first else "", geom, prop)) first = False else: out.write("{},{},{}\t\t{:.1f}\t\t{:.1f}{}".format(x, y, z, fg_ratio, qod, os.linesep)) if args.mode == "list": if args.geojson: out.write("]}") out.close() base_url = args.web_ui_base_url if args.web_ui_base_url else "./" if args.mode == "side" and args.web_ui: template = "compare.html" if not args.web_ui_template else args.web_ui_template web_ui(args.out, base_url, None, tiles_compare, args.format, template) if args.mode == "stack" and args.web_ui: template = "leaflet.html" if not args.web_ui_template else args.web_ui_template tiles = [tile for tile, _ in tiles_from_slippy_map(args.images[0])] web_ui(args.out, base_url, tiles, tiles_compare, args.format, template)
def worker(tile): x, y, z = list(map(str, tile)) if args.masks and args.labels: try: dist, fg_ratio, qod = compare(args.masks, args.labels, tile) except: progress.update() return False, tile if not args.minimum_fg <= fg_ratio <= args.maximum_fg or not args.minimum_qod <= qod <= args.maximum_qod: progress.update() return True, tile tiles_compare.append(tile) if args.mode == "side": for i, root in enumerate(args.images): img = tile_image_from_file( tile_from_slippy_map(root, x, y, z)[1]) if i == 0: side = np.zeros( (img.shape[0], img.shape[1] * len(args.images), 3)) side = np.swapaxes(side, 0, 1) if args.vertical else side image_shape = img.shape else: assert image_shape[0:2] == img.shape[ 0:2], "Unconsistent image size to compare" if args.vertical: side[i * image_shape[0]:(i + 1) * image_shape[0], :, :] = img else: side[:, i * image_shape[0]:(i + 1) * image_shape[0], :] = img tile_image_to_file(args.out, tile, np.uint8(side)) elif args.mode == "stack": for i, root in enumerate(args.images): tile_image = tile_image_from_file( tile_from_slippy_map(root, x, y, z)[1]) if i == 0: image_shape = tile_image.shape[0:2] stack = tile_image / len(args.images) else: assert image_shape == tile_image.shape[ 0:2], "Unconsistent image size to compare" stack = stack + (tile_image / len(args.images)) tile_image_to_file(args.out, tile, np.uint8(stack)) elif args.mode == "list": tiles_list.append([tile, fg_ratio, qod]) progress.update() return True, tile