changeset 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 3aa2d054848a
files colorize_labels.py colorize_labels.xml test-data/input2.tif test-data/output1.png test-data/output2.png
diffstat 5 files changed, 81 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/colorize_labels.py	Tue Mar 12 23:00:45 2024 +0000
+++ b/colorize_labels.py	Wed Mar 13 19:08:34 2024 +0000
@@ -1,9 +1,12 @@
 import argparse
 
+import matplotlib.colors as mpl
+import networkx as nx
 import numpy as np
+import scipy.ndimage as ndi
 import skimage.io
+import skimage.morphology as morph
 import skimage.util
-import superdsm.render
 
 
 def color_hex_to_rgb_tuple(hex):
@@ -16,28 +19,66 @@
     )
 
 
+def build_label_adjacency_graph(im, radius, bg_label):
+    G = nx.Graph()
+    selem = morph.disk(radius)
+    for label in np.unique(im):
+
+        if label == bg_label:
+            continue
+
+        G.add_node(label)
+
+        cc = (im == label)
+        neighborhood = ndi.binary_dilation(cc, selem)
+        adjacent_labels = np.unique(im[neighborhood])
+
+        for adjacent_label in adjacent_labels:
+
+            if adjacent_label == bg_label or adjacent_label <= label:
+                continue
+
+            G.add_edge(label, adjacent_label)
+            G.add_edge(adjacent_label, label)
+
+    return G
+
+
 if __name__ == '__main__':
 
     parser = argparse.ArgumentParser()
     parser.add_argument('input', type=str)
     parser.add_argument('--bg_label', type=int)
     parser.add_argument('--bg_color', type=str)
-    parser.add_argument('--cmap', type=str, default='hsv')
-    parser.add_argument('--seed', type=int)
+    parser.add_argument('--radius', type=int)
     parser.add_argument('--output', type=str)
     args = parser.parse_args()
 
+    # Load image and normalize
     im = skimage.io.imread(args.input)
     im = np.squeeze(im)
     assert im.ndim == 2
 
-    im_colorized = superdsm.render.colorize_labels(
-        labels=im,
-        bg_label=args.bg_label,
-        cmap=args.cmap,
-        bg_color=np.divide(color_hex_to_rgb_tuple(args.bg_color), 255),
-        shuffle=args.seed,
-    )
+    # Build adjacency graph of the labels
+    G = build_label_adjacency_graph(im, args.radius, args.bg_label)
+
+    # 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()))
+    node_colors = [graph_color_to_mpl_color[graph_coloring[n]] for n in G.nodes()]
 
-    im_colorized = skimage.util.img_as_ubyte(im_colorized)
-    skimage.io.imsave(args.output, im_colorized)
+    # Render result
+    bg_color_rgb = color_hex_to_rgb_tuple(args.bg_color)
+    result = np.dstack([np.full(im.shape, bg_color_rgb[ch], np.uint8) for ch in range(3)])
+    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]
+
+    # Write result image
+    skimage.io.imsave(args.output, result)
--- a/colorize_labels.xml	Tue Mar 12 23:00:45 2024 +0000
+++ b/colorize_labels.xml	Wed Mar 13 19:08:34 2024 +0000
@@ -1,19 +1,15 @@
 <tool id="colorize_labels" name="Colorize label map" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.05">
-    <description>with SuperDSM</description>
+    <description>with NetworkX</description>
     <macros>
-        <token name="@TOOL_VERSION@">0.2.0</token>
+        <token name="@TOOL_VERSION@">3.2.1</token>
         <token name="@VERSION_SUFFIX@">0</token>
     </macros>
     <edam_operations>
         <edam_operation>operation_3443</edam_operation>
     </edam_operations>
-    <xrefs>
-        <xref type="bio.tools">superdsm</xref>
-        <xref type="biii">superdsm</xref>
-    </xrefs>
     <requirements>
-        <requirement type="package" version="0.2.0">superdsm</requirement>
-        <requirement type="package" version="1.20">numpy</requirement>
+        <requirement type="package" version="3.2.1">networkx</requirement>
+        <requirement type="package" version="1.22">numpy</requirement>
         <requirement type="package" version="0.18.1">scikit-image</requirement>
     </requirements>
     <command><![CDATA[
@@ -21,7 +17,7 @@
     ## Inputs
     
     python '$__tool_directory__/colorize_labels.py' '$input'
-    --seed $seed
+    --radius $radius
     --bg_label $bg_label
     --bg_color '$bg_color'
     
@@ -33,7 +29,7 @@
     </command>
     <inputs>
         <param name="input" type="data" format="tiff,png" label="Input image (label map)" />
-        <param argument="--seed" type="integer" value="0" label="Randomization seed" />
+        <param argument="--radius" type="integer" min="1" value="10" label="Radius of the neighborhood" help="Defines the neighborhood (in pixels) where labels are considered to be adjacent." />
         <param argument="--bg_label" type="integer" value="0" label="Background label" />
         <param argument="--bg_color" type="color" value="#000000" label="Background color"/>
     </inputs>
@@ -42,14 +38,22 @@
     </outputs>
     <tests>
         <test>
-            <param name="input" value="input1.tif"/>
-            <param name="bg_label" value="0"/>
-            <param name="bg_color" value="#5a5a5a"/>
-            <output name="output" value="output1.png" ftype="png" compare="sim_size" delta_frac="0.1"/>
+            <param name="input" value="input1.tif" />
+            <param name="radius" value="1" />
+            <param name="bg_label" value="0" />
+            <param name="bg_color" value="#5a5a5a" />
+            <output name="output" value="output1.png" ftype="png" compare="sim_size" delta_frac="0.1" />
+        </test>
+        <test>
+            <param name="input" value="input2.tif" />
+            <param name="radius" value="10" />
+            <param name="bg_label" value="0" />
+            <param name="bg_color" value="#ffffff" />
+            <output name="output" value="output2.png" ftype="png" compare="sim_size" delta_frac="0.1" />
         </test>
     </tests>
     <help>
-        Colorize a 2-D label map for visualization.
+        Colorize a 2-D label map for visualization using greedy coloring.
 
         Label maps are produced by segmentation and other image analysis steps.
         Direct inspection of label maps can be difficult,
@@ -59,6 +63,14 @@
         label maps to color images, by assigning each label a unique color.
     </help>
     <citations>
-        <citation type="doi">10.1109/TPAMI.2022.3185583</citation>
+        <citation type="bibtex">
+        @inproceedings{networkx,
+          author = {Hagberg, Aric A. and Schult, Daniel A. and Swart, Pieter J.},
+          title = {Exploring network structure, dynamics, and function using {NetworkX}},
+          booktitle = {Proc. of the 7th Python in Science Conference (SciPy 2008)},
+          pages = {11--15},
+          year = {2008},
+        }
+        </citation>
     </citations>
 </tool>
Binary file test-data/input2.tif has changed
Binary file test-data/output1.png has changed
Binary file test-data/output2.png has changed