From c59405bd4e95cc616f93837d588ef30f03816c61 Mon Sep 17 00:00:00 2001 From: Leonid Kostrykin Date: Tue, 24 Sep 2024 14:02:32 +0200 Subject: [PATCH] Use variable-length color maps to fix previously failing test --- tools/colorize_labels/colorize_labels.py | 18 ++++++++++++++---- tools/colorize_labels/test-data/output1.png | Bin 98 -> 104 bytes tools/colorize_labels/test-data/output2.png | Bin 826 -> 771 bytes tools/colorize_labels/test-data/output3.png | Bin 0 -> 12986 bytes 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 tools/colorize_labels/test-data/output3.png diff --git a/tools/colorize_labels/colorize_labels.py b/tools/colorize_labels/colorize_labels.py index 24e2d61b..409b4195 100644 --- a/tools/colorize_labels/colorize_labels.py +++ b/tools/colorize_labels/colorize_labels.py @@ -1,7 +1,7 @@ import argparse import giatools.io -import matplotlib.colors as mpl +import matplotlib.pyplot as plt import networkx as nx import numpy as np import scipy.ndimage as ndi @@ -43,6 +43,18 @@ def build_label_adjacency_graph(im, radius, bg_label): return G +def get_n_unique_mpl_colors(n, colormap='jet', cyclic=False): + """ + Yields `n` unique colors from the given `colormap`. + + Set `cyclic` to `True` if the `colormap` is cyclic. + """ + cmap = plt.get_cmap(colormap) + m = n if cyclic else n - 1 + for i in range(n): + yield np.multiply(255, cmap(i / m)) + + if __name__ == '__main__': parser = argparse.ArgumentParser() @@ -60,14 +72,13 @@ def build_label_adjacency_graph(im, radius, bg_label): # Build adjacency graph of the labels G = build_label_adjacency_graph(im, args.radius, args.bg_label) - print('---') # Apply greedy coloring graph_coloring = nx.greedy_color(G) unique_colors = frozenset(graph_coloring.values()) # Assign colors to nodes based on the greedy coloring - graph_color_to_mpl_color = dict(zip(unique_colors, mpl.TABLEAU_COLORS.values())) + graph_color_to_mpl_color = dict(zip(unique_colors, get_n_unique_mpl_colors(len(unique_colors)))) node_colors = [graph_color_to_mpl_color[graph_coloring[n]] for n in G.nodes()] # Render result @@ -76,7 +87,6 @@ def build_label_adjacency_graph(im, radius, bg_label): for label, label_color in zip(G.nodes(), node_colors): cc = (im == label) - label_color = color_hex_to_rgb_tuple(label_color) for ch in range(3): result[:, :, ch][cc] = label_color[ch] diff --git a/tools/colorize_labels/test-data/output1.png b/tools/colorize_labels/test-data/output1.png index 5a226afd15fa128513b4c505105618225d20dec0..b70b94f2cecf0aee9b4e0394a1f389edd2ec0c89 100644 GIT binary patch delta 73 zcmYewn4sdK@9E+gQZXmFr>iT;fvJaw=j(}@X)9LT)~I1)YfC*HA}Jy9N>XZJ&5B8> bJV3y}Rm^_z=eM=Z3_#%N>gTe~DWM4f0}&eE delta 67 zcmc~unxJB*>FMGaQZXmFr>iT;fl0?bHSp)P{^<)pNJ>a3c*zyGIQ|S!UBv?g49;^n U+RvU6Uc>+dp00i_>zopr06NGQEC2ui diff --git a/tools/colorize_labels/test-data/output2.png b/tools/colorize_labels/test-data/output2.png index d089928b72b00cdf768dcfd5c3058fbe832e4f0a..006ead0b441beaa5b77c9e75caf5ee56b0f56ad9 100644 GIT binary patch delta 748 zcmV3*MYJSuQsfbg>qCu2R%*?FUnFT4b%mqrHXY*oDby^?&gO0H&vn{y-wO9>-ox zUc=?B{!BXLb!0_;SCK78SdN4f-Cur_!s3UD#yQc8^X4&l{zHNwZ59Od+54a*8ZK`q zGiSbVqUp2^>#Oj&xw1)MDb;K(n#^3)Uz*JG?jIOOR+S z`-%Q}P`i>=&m@iC`Z4_*0qfWCfW=sbmDSUbEKLx1%Yv@$jR^q$;8;o~h?|krTByeB z!;96=xEIJTQD!s5T5R9pY$hj&S9`M(zvT50zx|SZL4WFnoXv#d^J;4<+M5zeU4I5V zRx1+#gmpsA1dJ2AFgZCg3k8=6$Lh%BW%f27&Zta&1_0|tnyUsVm{RmId#g-9vz+M^ z)VpaeoO>x5Agnd~7W~M~2=t7}JJIKD@+M9f8FBo|D=ea#nfI$`OiQ$7`Bj6`(+4E#uWIFtR~A--eh(pu88rA$fCY>BG;_h$ z9-fJ-*Pg6wSznqa9e(j24hWmg1QTNnvexOT*Pc`xU0}eB9;ZQA;~&r90nNGPo9~;1 znM17wkTvI)$$!(TSaM|Dt9>KS>tq`AH?dfHw5O3F?F5iT*oh&|8uT}fTQXZOanPDfYWM%ex_?TbTK7N_T zni@Di-v3&-O=A*d+?(zLBJHo$oP$nut$b1b`f2zb&m_p0Gx((aH8hez3MD>2gRlab zxI~=r${Fp6VhkoOPPTsN@rW5KB9qYW;)Y(F*-r8tW9&lVmU1^?=c8kBGUNf2)tP2N zk&|Y*On(TGd2LlzkCImoKiX=9H0coPaxQUhTdhS)NB}uYe!;|GCq^U_K(;+DGdZxB zos8#6wC;mWrZBm&Y)sY^8llYZM`w*ch$u_zn>nji zTPDqAcA^sb|Gf-Y3KOAKj4AMyjM9N+w38PZzJKWekWFC$zN59*0aY8_YNIPx17^OpY)jH?Av(Nx0%mZt{Q(>*~-B=olJ)8CE>}ePIR{RMI6NUw=gv~S5VuH ilO0i7wl2+R1N;xZbs1jjU?{Z!0000Xq@TVM45 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 S{HuRb0NNV*>eXsCq5lUX!UClL literal 0 HcmV?d00001