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)