Mercurial > repos > imgteam > split_image
changeset 3:d45a07063da1 draft default tip
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/split_image/ commit df96ae15da34285b0a9d435a48924665fff37d6a
| author | imgteam |
|---|---|
| date | Sat, 04 Apr 2026 21:22:07 +0000 |
| parents | 227e8928af6e |
| children | |
| files | split.py split_image.xml test-data/multiseries_series6.tiff test-data/zcyx_slice01.tiff test-data/zcyx_slice10.tiff test-data/zcyx_slice18.tiff test-data/zcyx_slice25.tiff |
| diffstat | 7 files changed, 87 insertions(+), 76 deletions(-) [+] |
line wrap: on
line diff
--- a/split.py Fri Dec 12 21:02:25 2025 +0000 +++ b/split.py Sat Apr 04 21:22:07 2026 +0000 @@ -1,33 +1,45 @@ import argparse import math -import os import pathlib -import shutil import giatools +import giatools.io import numpy as np -import tifffile class OutputWriter: - def __init__(self, dir_path: pathlib.Path, num_images: int, squeeze: bool, verbose: bool): - print(f'Writing {num_images} image(s)') + def __init__( + self, + dir_path: pathlib.Path, + num_images: int, + squeeze: bool, + verbose: bool, + offset: int = 0, + step: int = 1, + count: int | None = None, + ): + self.positions = np.arange(num_images)[offset::step] + 1 + if count is not None: + self.positions = self.positions[:count] + + print(f'Writing {len(self.positions)} out of {num_images} image(s)') decimals = math.ceil(math.log10(1 + num_images)) self.output_filepath_pattern = str(dir_path / f'%0{decimals}d.tiff') - self.last_idx = 0 + self.last_pos = 0 self.squeeze = squeeze self.verbose = verbose def write(self, img: giatools.Image): - self.last_idx += 1 - if self.squeeze: - img = img.squeeze() - if self.last_idx == 1 or self.verbose: - prefix = f'Output {self.last_idx}' if self.verbose else 'Output' - print(f'{prefix} axes:', img.axes) - print(f'{prefix} shape:', img.data.shape) - img.write(self.output_filepath_pattern % self.last_idx) + self.last_pos += 1 + if self.last_pos in self.positions: + if self.squeeze: + img = img.squeeze() + if self.last_pos == self.positions[0] or self.verbose: + prefix = f'Output {self.last_pos}' if self.verbose else 'Output' + print(f'{prefix} axes:', img.axes) + print(f'{prefix} shape:', img.data.shape) + img.write(self.output_filepath_pattern % self.last_pos) if __name__ == '__main__': @@ -37,52 +49,31 @@ parser.add_argument('axis', type=str, choices=list(giatools.default_normalized_axes) + ['S', '']) parser.add_argument('output', type=pathlib.Path) parser.add_argument('--squeeze', action='store_true', default=False) + parser.add_argument('offset', type=int) + parser.add_argument('step', type=int) + parser.add_argument('--count', type=int) args = parser.parse_args() # If splitting a file that contains multiple images... if args.axis == '': - # Peek the number of series in the input file (if it is a TIFF) - try: - with tifffile.TiffFile(args.input) as tiff: - num_tiff_series = len(tiff.series) - print(f'Found TIFF with {num_tiff_series} series') - except tifffile.TiffFileError: - num_tiff_series = 0 # not a TIFF file - print('Not a TIFF file') + # Peek the number of images + num_images = giatools.io.peek_num_images_in_file(args.input) + print(f'Found {num_images} image(s) in file') - # If the file is a multi-series TIFF, extract the individual series - # (for consistency, also accept only a single series if squeezing is requested) - if num_tiff_series >= 2 or (num_tiff_series == 1 and args.squeeze): - output = OutputWriter( - dir_path=args.output, - num_images=num_tiff_series, - squeeze=args.squeeze, - verbose=True, - ) - for series in range(num_tiff_series): - img = giatools.Image.read(args.input, series=series) - output.write( - img.squeeze_like(img.original_axes), - ) - - # Otherwise, there is nothing to be split (or squeeze) - # (the input is either a single-series TIFF or not a TIFF at all) - elif num_tiff_series == 1: # input is a single-series TIFF (output = input) - try: - os.symlink(args.input, args.output / '1.tiff') - except OSError: - shutil.copyfile(args.input, args.output / '1.tiff') - else: # input is not a TIFF, conversion needed - img = giatools.Image.read(args.input) - OutputWriter( - dir_path=args.output, - num_images=1, - squeeze=args.squeeze, - verbose=False, - ).write( - img.squeeze_like(img.original_axes), - ) + # Extract the individual images + output = OutputWriter( + dir_path=args.output, + num_images=num_images, + squeeze=args.squeeze, + verbose=(num_images > 1), + offset=args.offset, + step=args.step, + count=args.count, + ) + for position in range(num_images): + img = giatools.Image.read(args.input, position=position, normalize_axes=None) + output.write(img) # If splitting along an image axes... else: @@ -105,6 +96,9 @@ num_images=arr.shape[0], squeeze=args.squeeze, verbose=False, + offset=args.offset, + step=args.step, + count=args.count, ) for img_idx, img in enumerate(arr): img = np.moveaxis(img[None], 0, axis_pos)
--- a/split_image.xml Fri Dec 12 21:02:25 2025 +0000 +++ b/split_image.xml Sat Apr 04 21:22:07 2026 +0000 @@ -4,7 +4,7 @@ <import>creators.xml</import> <import>tests.xml</import> <token name="@TOOL_VERSION@">2.3.5</token> - <token name="@VERSION_SUFFIX@">0</token> + <token name="@VERSION_SUFFIX@">1</token> </macros> <creator> <expand macro="creators/bmcv"/> @@ -18,9 +18,11 @@ </xrefs> <requirements> <requirement type="package" version="@TOOL_VERSION@">numpy</requirement> - <requirement type="package" version="0.5.2">giatools</requirement> - <requirement type="package" version="2025.10.16">tifffile</requirement> + <requirement type="package" version="0.7.3">giatools</requirement> </requirements> + <required_files> + <include type="glob" path="*.py"/> + </required_files> <command detect_errors="aggressive"><![CDATA[ mkdir output && @@ -30,11 +32,17 @@ '$axis' output + $offset + $step $squeeze + #if str($count) != "" + --count $count + #end if + ]]></command> <inputs> - <param name="input" type="data" format="tiff,png" label="Image to split" /> + <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> @@ -44,11 +52,17 @@ <option value="">Split dataset that contains multiple images (e.g., multi-series TIFF)</option> </param> <param name="squeeze" type="boolean" checked="false" truevalue="--squeeze" falsevalue="" label="Squeeze result images" - help="Only non-singleton axes (axes with more than one element) will be retained in the result images. This does not apply for the X and Y axes which always are retained." /> + help="Only non-singleton axes (axes with more than one element) will be retained in the result images. This does not apply for the X and Y axes which always are retained."/> + <param name="offset" type="integer" value="0" min="0" label="Offset" + help="Number of slices to skip at the beginning."/> + <param name="step" type="integer" value="1" min="1" label="Step" + help="Number of slices between extracted images (each slice is extracted for a value of 1, each second slice is extracted for a value of two, and so on)."/> + <param name="count" type="integer" optional="true" min="1" label="Count" + help="Maximum number of slices to extract."/> </inputs> <outputs> <collection type="list" name="output" label="Split ${on_string} along ${axis} axis"> - <discover_datasets directory="output" pattern="__name__" format="tiff" /> + <discover_datasets directory="output" pattern="__name__" format="tiff"/> </collection> </outputs> <tests> @@ -66,7 +80,7 @@ <assert_stdout> <has_line line="Input image axes: YXC"/> <has_line line="Input image shape: (32, 32, 3)"/> - <has_line line="Writing 3 image(s)"/> + <has_line line="Writing 3 out of 3 image(s)"/> <has_line line="Output axes: YXC"/> <has_line line="Output shape: (32, 32, 1)"/> </assert_stdout> @@ -79,8 +93,8 @@ <expand macro="tests/intensity_image_diff/element" name="1.tiff" value="rgb1.tiff" ftype="tiff"/> </output_collection> <assert_stdout> - <has_line line="Not a TIFF file"/> - <has_line line="Writing 1 image(s)"/> + <has_line line="Found 1 image(s) in file"/> + <has_line line="Writing 1 out of 1 image(s)"/> <has_line line="Output axes: YXC"/> <has_line line="Output shape: (32, 32, 3)"/> </assert_stdout> @@ -88,17 +102,20 @@ <!-- 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"/> + <param name="input" value="zcyx.tiff"/> + <param name="axis" value="Z"/> + <param name="squeeze" value="false"/> + <param name="offset" value="9"/> + <param name="step" value="2"/> + <param name="count" value="5"/> + <output_collection name="output" type="list" count="5"> + <expand macro="tests/intensity_image_diff/element" name="10.tiff" value="zcyx_slice10.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="18.tiff" value="zcyx_slice18.tiff" ftype="tiff"/> </output_collection> <assert_stdout> <has_line line="Input image axes: ZCYX"/> <has_line line="Input image shape: (25, 2, 50, 50)"/> - <has_line line="Writing 25 image(s)"/> + <has_line line="Writing 5 out of 25 image(s)"/> <has_line line="Output axes: ZCYX"/> <has_line line="Output shape: (1, 2, 50, 50)"/> </assert_stdout> @@ -114,7 +131,7 @@ <assert_stdout> <has_line line="Input image axes: QYX"/> <has_line line="Input image shape: (2, 256, 256)"/> - <has_line line="Writing 2 image(s)"/> + <has_line line="Writing 2 out of 2 image(s)"/> <has_line line="Output axes: QYX"/> <has_line line="Output shape: (1, 256, 256)"/> </assert_stdout> @@ -127,7 +144,7 @@ <expand macro="tests/intensity_image_diff/element" name="1.tiff" value="qyx.tiff" ftype="tiff"/> </output_collection> <assert_stdout> - <has_line line="Found TIFF with 1 series"/> + <has_line line="Found 1 image(s) in file"/> </assert_stdout> </test> @@ -141,8 +158,8 @@ <expand macro="tests/intensity_image_diff/element" name="6.tiff" value="multiseries_series6.tiff" ftype="tiff"/> </output_collection> <assert_stdout> - <has_line line="Found TIFF with 6 series"/> - <has_line line="Writing 6 image(s)"/> + <has_line line="Found 6 image(s) in file"/> + <has_line line="Writing 6 out of 6 image(s)"/> <has_line line="Output 1 axes: CYX"/> <has_line line="Output 1 shape: (4, 5, 5)"/> <has_line line="Output 2 axes: CYX"/> @@ -171,7 +188,7 @@ <assert_stdout> <has_line line="Input image axes: YXC"/> <has_line line="Input image shape: (32, 32, 3)"/> - <has_line line="Writing 3 image(s)"/> + <has_line line="Writing 3 out of 3 image(s)"/> <has_line line="Output axes: YX"/> <has_line line="Output shape: (32, 32)"/> </assert_stdout> @@ -188,7 +205,7 @@ <assert_stdout> <has_line line="Input image axes: YXC"/> <has_line line="Input image shape: (32, 32, 3)"/> - <has_line line="Writing 1 image(s)"/> + <has_line line="Writing 1 out of 1 image(s)"/> <has_line line="Output axes: YXC"/> <has_line line="Output shape: (32, 32, 3)"/> </assert_stdout>
