-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlabel_colorizer.py
71 lines (59 loc) · 2.07 KB
/
label_colorizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/env python3.11
"""Utility to assign random colors to values in a grayscale integer array saved as a GeoTIFF."""
import typer
import pathlib
import rasterio
import numpy as np
from rasterio.enums import ColorInterp
import colorsys
import tqdm
app = typer.Typer()
@app.command()
def main(
input_path: pathlib.Path,
output_path: pathlib.Path,
mask_value: int = 0,
seed: int = 42,
randomize: bool = True,
):
with rasterio.open(input_path) as in_dataset:
assert in_dataset.count == 1, "There should be only one band in the dataset"
band1 = in_dataset.read(1)
max_value = int(band1.max())
all_values = range(1, max_value + 1)
rng = np.random.default_rng(seed)
if randomize:
hsv_tuples = {i: (rng.uniform(), 1, 1) for i in all_values}
else:
hsv_tuples = {i: (i * 1.0 / max_value, 1, 1) for i in all_values}
rgba_values = {i: (*colorsys.hsv_to_rgb(*hsv_tuples[i]), 1) for i in all_values}
rgba_values[mask_value] = (0, 0, 0, 0)
red = np.zeros(band1.shape)
green = np.zeros(band1.shape)
blue = np.zeros(band1.shape)
alpha = np.zeros(band1.shape)
for (x, y), value in tqdm.tqdm(np.ndenumerate(band1), total=np.prod(band1.shape)):
rgba = rgba_values[value]
red[x, y] = int(255 * rgba[0])
green[x, y] = int(255 * rgba[1])
blue[x, y] = int(255 * rgba[2])
alpha[x, y] = int(255 * rgba[3])
new_profile = in_dataset.profile
new_profile.update(
nodata=0,
dtype="uint8",
count=4,
colorinterp=[
ColorInterp.red,
ColorInterp.green,
ColorInterp.blue,
ColorInterp.alpha,
],
)
with rasterio.open(output_path, mode="w", **new_profile) as out_dataset:
out_dataset.write(red, 1)
out_dataset.write(green, 2)
out_dataset.write(blue, 3)
out_dataset.write(alpha, 4)
if __name__ == "__main__":
app()