comparison colorize_labels.py @ 4:5907be5a8d7c draft default tip

planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/colorize_labels commit 4344f548f365dba87c20188d6e3c2df8630d2313
author imgteam
date Tue, 24 Sep 2024 17:30:20 +0000
parents 2d1de6e7b113
children
comparison
equal deleted inserted replaced
3:2d1de6e7b113 4:5907be5a8d7c
1 import argparse 1 import argparse
2 2
3 import giatools.io 3 import giatools.io
4 import matplotlib.colors as mpl 4 import matplotlib.pyplot as plt
5 import networkx as nx 5 import networkx as nx
6 import numpy as np 6 import numpy as np
7 import scipy.ndimage as ndi 7 import scipy.ndimage as ndi
8 import skimage.io 8 import skimage.io
9 import skimage.morphology as morph
10 import skimage.util 9 import skimage.util
11 10
12 11
13 def color_hex_to_rgb_tuple(hex): 12 def color_hex_to_rgb_tuple(hex):
14 if hex.startswith('#'): 13 if hex.startswith('#'):
20 ) 19 )
21 20
22 21
23 def build_label_adjacency_graph(im, radius, bg_label): 22 def build_label_adjacency_graph(im, radius, bg_label):
24 G = nx.Graph() 23 G = nx.Graph()
25 selem = morph.disk(radius)
26 for label in np.unique(im): 24 for label in np.unique(im):
27 25
28 if label == bg_label: 26 if label == bg_label:
29 continue 27 continue
30 28
31 G.add_node(label) 29 G.add_node(label)
32 30
33 cc = (im == label) 31 cc = (im == label)
34 neighborhood = ndi.binary_dilation(cc, selem) 32 neighborhood = (ndi.distance_transform_edt(~cc) <= radius)
35 adjacent_labels = np.unique(im[neighborhood]) 33 adjacent_labels = np.unique(im[neighborhood])
36 34
37 for adjacent_label in adjacent_labels: 35 for adjacent_label in adjacent_labels:
38 36
39 if adjacent_label == bg_label or adjacent_label <= label: 37 if adjacent_label == bg_label or adjacent_label <= label:
41 39
42 G.add_edge(label, adjacent_label) 40 G.add_edge(label, adjacent_label)
43 G.add_edge(adjacent_label, label) 41 G.add_edge(adjacent_label, label)
44 42
45 return G 43 return G
44
45
46 def get_n_unique_mpl_colors(n, colormap='jet', cyclic=False):
47 """
48 Yields `n` unique colors from the given `colormap`.
49
50 Set `cyclic` to `True` if the `colormap` is cyclic.
51 """
52 cmap = plt.get_cmap(colormap)
53 m = n if cyclic else n - 1
54 for i in range(n):
55 yield np.multiply(255, cmap(i / m))
46 56
47 57
48 if __name__ == '__main__': 58 if __name__ == '__main__':
49 59
50 parser = argparse.ArgumentParser() 60 parser = argparse.ArgumentParser()
66 # Apply greedy coloring 76 # Apply greedy coloring
67 graph_coloring = nx.greedy_color(G) 77 graph_coloring = nx.greedy_color(G)
68 unique_colors = frozenset(graph_coloring.values()) 78 unique_colors = frozenset(graph_coloring.values())
69 79
70 # Assign colors to nodes based on the greedy coloring 80 # Assign colors to nodes based on the greedy coloring
71 graph_color_to_mpl_color = dict(zip(unique_colors, mpl.TABLEAU_COLORS.values())) 81 graph_color_to_mpl_color = dict(zip(unique_colors, get_n_unique_mpl_colors(len(unique_colors))))
72 node_colors = [graph_color_to_mpl_color[graph_coloring[n]] for n in G.nodes()] 82 node_colors = [graph_color_to_mpl_color[graph_coloring[n]] for n in G.nodes()]
73 83
74 # Render result 84 # Render result
75 bg_color_rgb = color_hex_to_rgb_tuple(args.bg_color) 85 bg_color_rgb = color_hex_to_rgb_tuple(args.bg_color)
76 result = np.dstack([np.full(im.shape, bg_color_rgb[ch], np.uint8) for ch in range(3)]) 86 result = np.dstack([np.full(im.shape, bg_color_rgb[ch], np.uint8) for ch in range(3)])
77 for label, label_color in zip(G.nodes(), node_colors): 87 for label, label_color in zip(G.nodes(), node_colors):
78 88
79 cc = (im == label) 89 cc = (im == label)
80 label_color = color_hex_to_rgb_tuple(label_color)
81 for ch in range(3): 90 for ch in range(3):
82 result[:, :, ch][cc] = label_color[ch] 91 result[:, :, ch][cc] = label_color[ch]
83 92
84 # Write result image 93 # Write result image
85 skimage.io.imsave(args.output, result) 94 skimage.io.imsave(args.output, result)