Mercurial > repos > imgteam > colorize_labels
comparison colorize_labels.py @ 1:43c80f3c3b60 draft
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/colorize_labels commit 98270c8f2805d406e0d88605fde778f8f182df9b
author | imgteam |
---|---|
date | Wed, 13 Mar 2024 19:08:34 +0000 |
parents | 0afb17e107ff |
children | 2d1de6e7b113 |
comparison
equal
deleted
inserted
replaced
0:0afb17e107ff | 1:43c80f3c3b60 |
---|---|
1 import argparse | 1 import argparse |
2 | 2 |
3 import matplotlib.colors as mpl | |
4 import networkx as nx | |
3 import numpy as np | 5 import numpy as np |
6 import scipy.ndimage as ndi | |
4 import skimage.io | 7 import skimage.io |
8 import skimage.morphology as morph | |
5 import skimage.util | 9 import skimage.util |
6 import superdsm.render | |
7 | 10 |
8 | 11 |
9 def color_hex_to_rgb_tuple(hex): | 12 def color_hex_to_rgb_tuple(hex): |
10 if hex.startswith('#'): | 13 if hex.startswith('#'): |
11 hex = hex[1:] | 14 hex = hex[1:] |
14 int(hex[2:4], 16), | 17 int(hex[2:4], 16), |
15 int(hex[4:6], 16), | 18 int(hex[4:6], 16), |
16 ) | 19 ) |
17 | 20 |
18 | 21 |
22 def build_label_adjacency_graph(im, radius, bg_label): | |
23 G = nx.Graph() | |
24 selem = morph.disk(radius) | |
25 for label in np.unique(im): | |
26 | |
27 if label == bg_label: | |
28 continue | |
29 | |
30 G.add_node(label) | |
31 | |
32 cc = (im == label) | |
33 neighborhood = ndi.binary_dilation(cc, selem) | |
34 adjacent_labels = np.unique(im[neighborhood]) | |
35 | |
36 for adjacent_label in adjacent_labels: | |
37 | |
38 if adjacent_label == bg_label or adjacent_label <= label: | |
39 continue | |
40 | |
41 G.add_edge(label, adjacent_label) | |
42 G.add_edge(adjacent_label, label) | |
43 | |
44 return G | |
45 | |
46 | |
19 if __name__ == '__main__': | 47 if __name__ == '__main__': |
20 | 48 |
21 parser = argparse.ArgumentParser() | 49 parser = argparse.ArgumentParser() |
22 parser.add_argument('input', type=str) | 50 parser.add_argument('input', type=str) |
23 parser.add_argument('--bg_label', type=int) | 51 parser.add_argument('--bg_label', type=int) |
24 parser.add_argument('--bg_color', type=str) | 52 parser.add_argument('--bg_color', type=str) |
25 parser.add_argument('--cmap', type=str, default='hsv') | 53 parser.add_argument('--radius', type=int) |
26 parser.add_argument('--seed', type=int) | |
27 parser.add_argument('--output', type=str) | 54 parser.add_argument('--output', type=str) |
28 args = parser.parse_args() | 55 args = parser.parse_args() |
29 | 56 |
57 # Load image and normalize | |
30 im = skimage.io.imread(args.input) | 58 im = skimage.io.imread(args.input) |
31 im = np.squeeze(im) | 59 im = np.squeeze(im) |
32 assert im.ndim == 2 | 60 assert im.ndim == 2 |
33 | 61 |
34 im_colorized = superdsm.render.colorize_labels( | 62 # Build adjacency graph of the labels |
35 labels=im, | 63 G = build_label_adjacency_graph(im, args.radius, args.bg_label) |
36 bg_label=args.bg_label, | |
37 cmap=args.cmap, | |
38 bg_color=np.divide(color_hex_to_rgb_tuple(args.bg_color), 255), | |
39 shuffle=args.seed, | |
40 ) | |
41 | 64 |
42 im_colorized = skimage.util.img_as_ubyte(im_colorized) | 65 # Apply greedy coloring |
43 skimage.io.imsave(args.output, im_colorized) | 66 graph_coloring = nx.greedy_color(G) |
67 unique_colors = frozenset(graph_coloring.values()) | |
68 | |
69 # Assign colors to nodes based on the greedy coloring | |
70 graph_color_to_mpl_color = dict(zip(unique_colors, mpl.TABLEAU_COLORS.values())) | |
71 node_colors = [graph_color_to_mpl_color[graph_coloring[n]] for n in G.nodes()] | |
72 | |
73 # Render result | |
74 bg_color_rgb = color_hex_to_rgb_tuple(args.bg_color) | |
75 result = np.dstack([np.full(im.shape, bg_color_rgb[ch], np.uint8) for ch in range(3)]) | |
76 for label, label_color in zip(G.nodes(), node_colors): | |
77 | |
78 cc = (im == label) | |
79 label_color = color_hex_to_rgb_tuple(label_color) | |
80 for ch in range(3): | |
81 result[:, :, ch][cc] = label_color[ch] | |
82 | |
83 # Write result image | |
84 skimage.io.imsave(args.output, result) |