Mercurial > repos > imgteam > split_image
changeset 0:6b42bec75e69 draft
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/split_image/ commit f1052360d410594fa1795cf0e02576b8fa4d4135
author | imgteam |
---|---|
date | Fri, 07 Mar 2025 08:08:05 +0000 |
parents | |
children | 73d7a4ffc03d |
files | creators.xml split.py split_image.xml test-data/rgb1.png test-data/rgb1_b.tiff test-data/rgb1_g.tiff test-data/rgb1_r.tiff test-data/rgb1_split_z.tiff test-data/rgb1_squeezed_b.tiff test-data/rgb1_squeezed_g.tiff test-data/rgb1_squeezed_r.tiff test-data/zcyx.tiff test-data/zcyx_slice01.tiff test-data/zcyx_slice25.tiff tests.xml |
diffstat | 15 files changed, 275 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/creators.xml Fri Mar 07 08:08:05 2025 +0000 @@ -0,0 +1,28 @@ +<macros> + + <xml name="creators/bmcv"> + <organization name="Biomedical Computer Vision Group, Heidelberg Universtiy" alternateName="BMCV" url="http://www.bioquant.uni-heidelberg.de/research/groups/biomedical_computer_vision.html" /> + <yield /> + </xml> + + <xml name="creators/rmassei"> + <person givenName="Riccardo" familyName="Massei"/> + <yield/> + </xml> + + <xml name="creators/alliecreason"> + <person givenName="Allison" familyName="Creason"/> + <yield/> + </xml> + + <xml name="creators/bugraoezdemir"> + <person givenName="Bugra" familyName="Oezdemir"/> + <yield/> + </xml> + + <xml name="creators/thawn"> + <person givenName="Till" familyName="Korten"/> + <yield/> + </xml> + +</macros>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/split.py Fri Mar 07 08:08:05 2025 +0000 @@ -0,0 +1,44 @@ +import argparse +import math + +import giatools +import giatools.util +import numpy as np +import tifffile + + +parser = argparse.ArgumentParser() +parser.add_argument('input', type=str) +parser.add_argument('axis', type=str) +parser.add_argument('output', type=str) +parser.add_argument('--squeeze', action='store_true', default=False) +args = parser.parse_args() + +# Validate and normalize input parameters +assert len(args.axis) == 1, 'Axis input must be a single character.' +axis = args.axis.replace('S', 'C') + +# Read input image as TZYXC +img_in = giatools.Image.read(args.input) + +# Determine the axis to split along +axis_pos = img_in.axes.index(axis) + +# Perform the splitting +arr = np.moveaxis(img_in.data, axis_pos, 0) +decimals = math.ceil(math.log10(1 + arr.shape[0])) +output_filename_pattern = f'{args.output}/%0{decimals}d.tiff' +for img_idx, img in enumerate(arr): + img = np.moveaxis(img[None], 0, axis_pos) + + # Optionally, squeeze the image + if args.squeeze: + s = [axis_pos for axis_pos in range(len(img_in.axes)) if img.shape[axis_pos] == 1 and img_in.axes[axis_pos] not in 'YX'] + img = np.squeeze(img, axis=tuple(s)) + img_axes = giatools.util.str_without_positions(img_in.axes, s) + else: + img_axes = img_in.axes + + # Save the result + filename = output_filename_pattern % (img_idx + 1) + tifffile.imwrite(filename, img, metadata=dict(axes=img_axes))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/split_image.xml Fri Mar 07 08:08:05 2025 +0000 @@ -0,0 +1,108 @@ +<tool id="ip_split_image" name="Split image along axes" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.05"> + <description>with NumPy</description> + <macros> + <import>creators.xml</import> + <import>tests.xml</import> + <token name="@TOOL_VERSION@">2.2.3</token> + <token name="@VERSION_SUFFIX@">0</token> + </macros> + <creator> + <expand macro="creators/bmcv"/> + </creator> + <edam_operations> + <edam_operation>operation_3443</edam_operation> + </edam_operations> + <requirements> + <requirement type="package" version="@TOOL_VERSION@">numpy</requirement> + <requirement type="package" version="0.3.2">giatools</requirement> + <requirement type="package" version="2024.7.24">tifffile</requirement> + </requirements> + <command detect_errors="aggressive"><![CDATA[ + + mkdir output && + python '$__tool_directory__/split.py' + + '$input' + '$axis' + output + + $squeeze + + ]]></command> + <inputs> + <param name="input" type="data" format="tiff,png" label="Image to split" /> + <param name="axis" type="select" label="Axis to split along"> + <option value="T">T-axis (split the frames of a temporal image sequence)</option> + <option value="Z">Z-axis (split the slices of a 3-D image or image sequence)</option> + <option value="C" selected="true">C-axis (split the channels of an image or image sequence)</option> + <option value="S">S-axis (split the samples of an image or image sequence)</option> + </param> + <param name="squeeze" type="boolean" checked="false" truevalue="--squeeze" falsevalue="" label="Squeeze result imags" help="Only axes with more than one element will be retained in the result images. Does not apply for X and Y axes." /> + </inputs> + <outputs> + <collection type="list" name="output" label="Split ${on_string} along ${axis} axis"> + <discover_datasets directory="output" pattern="__name__" format="tiff" /> + </collection> + </outputs> + <tests> + + <!-- PNG tests --> + <test> + <param name="input" value="rgb1.png" /> + <param name="axis" value="C" /> + <param name="squeeze" value="false" /> + <output_collection name="output" type="list" count="3"> + <expand macro="tests/intensity_image_diff/element" name="1.tiff" value="rgb1_r.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="2.tiff" value="rgb1_g.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="3.tiff" value="rgb1_b.tiff" ftype="tiff"/> + </output_collection> + </test> + + <!-- TIFF tests --> + <test> + <param name="input" value="zcyx.tiff" /> + <param name="axis" value="Z" /> + <param name="squeeze" value="false" /> + <output_collection name="output" type="list" count="25"> + <expand macro="tests/intensity_image_diff/element" name="01.tiff" value="zcyx_slice01.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="25.tiff" value="zcyx_slice25.tiff" ftype="tiff"/> + </output_collection> + </test> + + <!-- Test squeezing --> + <test> + <param name="input" value="rgb1.png" /> + <param name="axis" value="C" /> + <param name="squeeze" value="true" /> + <output_collection name="output" type="list" count="3"> + <expand macro="tests/intensity_image_diff/element" name="1.tiff" value="rgb1_squeezed_r.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="2.tiff" value="rgb1_squeezed_g.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="3.tiff" value="rgb1_squeezed_b.tiff" ftype="tiff"/> + </output_collection> + </test> + + <!-- Test with missing axes --> + <test> + <param name="input" value="rgb1.png" /> + <param name="axis" value="Z" /> + <param name="squeeze" value="false" /> + <output_collection name="output" type="list" count="1"> + <expand macro="tests/intensity_image_diff/element" name="1.tiff" value="rgb1_split_z.tiff" ftype="tiff"/> + </output_collection> + </test> + + </tests> + <help> + + **Splits an image along a specific axis (e.g., channels).** + + This tool splits an image along a specifc axis and yields a collection of images. + This can be used, for example, to convert a multi-channel image into a collection of single-channel images. + + The pixel data type of the split image is preserved (will be the same as the input image). + + </help> + <citations> + <citation type="doi">10.1038/s41586-020-2649-2</citation> + </citations> +</tool>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests.xml Fri Mar 07 08:08:05 2025 +0000 @@ -0,0 +1,95 @@ +<macros> + + <!-- Macros for verification of image outputs --> + + <xml + name="tests/binary_image_diff" + tokens="name,value,ftype,metric,eps" + token_metric="mae" + token_eps="0.01"> + + <output name="@NAME@" value="@VALUE@" ftype="@FTYPE@" compare="image_diff" metric="@METRIC@" eps="@EPS@" pin_labels="0"> + <assert_contents> + <has_image_n_labels n="2"/> + <yield/> + </assert_contents> + </output> + + </xml> + + <xml + name="tests/label_image_diff" + tokens="name,value,ftype,metric,eps,pin_labels" + token_metric="iou" + token_eps="0.01" + token_pin_labels="0"> + + <output name="@NAME@" value="@VALUE@" ftype="@FTYPE@" compare="image_diff" metric="@METRIC@" eps="@EPS@" pin_labels="@PIN_LABELS@"> + <assert_contents> + <yield/> + </assert_contents> + </output> + + </xml> + + <xml + name="tests/intensity_image_diff" + tokens="name,value,ftype,metric,eps" + token_metric="rms" + token_eps="0.01"> + + <output name="@NAME@" value="@VALUE@" ftype="@FTYPE@" compare="image_diff" metric="@METRIC@" eps="@EPS@"> + <assert_contents> + <yield/> + </assert_contents> + </output> + + </xml> + + <!-- Variants of the above for verification of collection elements --> + + <xml + name="tests/binary_image_diff/element" + tokens="name,value,ftype,metric,eps" + token_metric="mae" + token_eps="0.01"> + + <element name="@NAME@" value="@VALUE@" ftype="@FTYPE@" compare="image_diff" metric="@METRIC@" eps="@EPS@" pin_labels="0"> + <assert_contents> + <has_image_n_labels n="2"/> + <yield/> + </assert_contents> + </element> + + </xml> + + <xml + name="tests/label_image_diff/element" + tokens="name,value,ftype,metric,eps" + token_metric="iou" + token_eps="0.01" + token_pin_labels="0"> + + <element name="@NAME@" value="@VALUE@" ftype="@FTYPE@" compare="image_diff" metric="@METRIC@" eps="@EPS@" pin_labels="@PIN_LABELS@"> + <assert_contents> + <yield/> + </assert_contents> + </element> + + </xml> + + <xml + name="tests/intensity_image_diff/element" + tokens="name,value,ftype,metric,eps" + token_metric="rms" + token_eps="0.01"> + + <element name="@NAME@" value="@VALUE@" ftype="@FTYPE@" compare="image_diff" metric="@METRIC@" eps="@EPS@"> + <assert_contents> + <yield/> + </assert_contents> + </element> + + </xml> + +</macros>