Mercurial > repos > imgteam > slice_image
changeset 3:1faa7e3c94ff draft
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/slice_image/ commit c045f067a57e8308308cf6329060c7ccd3fc372f
author | imgteam |
---|---|
date | Thu, 04 Apr 2024 15:26:38 +0000 |
parents | f312d414f234 |
children | a72590196440 |
files | creators.xml slice_image.py slice_image.xml tests.xml |
diffstat | 4 files changed, 190 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/creators.xml Thu Apr 04 15:26:38 2024 +0000 @@ -0,0 +1,23 @@ +<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/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>
--- a/slice_image.py Mon Nov 13 22:12:22 2023 +0000 +++ b/slice_image.py Thu Apr 04 15:26:38 2024 +0000 @@ -9,12 +9,9 @@ import skimage.util -def slice_image(input_file, out_folder, label=None, label_out_folder=None, window_size=64, - stride=1, bg_thresh=1, limit_slices=False, n_thresh=5000, seed=None): - # TODO NOT Implemented:process labels - # --> label and label_out_folder useless so far +def slice_image(input_file, out_folder, window_size=64, stride=1, bg_thresh=1, limit_slices=False, n_thresh=5000, seed=None): - # primarily for testing purposes: + # Primarily for testing purposes if seed is not None: random.seed(seed) @@ -40,7 +37,7 @@ sum_image = skimage.util.img_as_uint(sum_image) g = skimage.feature.greycomatrix(sum_image, [1, 2], [0, np.pi / 2], nnormed=True, symmetric=True) hom = np.var(skimage.feature.greycoprops(g, prop='homogeneity')) - if hom > bg_thresh: # 0.0005 + if hom > bg_thresh: continue if limit_slices: @@ -54,19 +51,22 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument('input_file', type=argparse.FileType('r'), help='input file') - parser.add_argument('out_folder', help='out folder') - parser.add_argument('--label', dest='label_file', default=None, help='auxiliary label file to split in the same way') - parser.add_argument('--label_out_folder', dest='label_out_folder', default=None, help='label out folder') - parser.add_argument('--stride', dest='stride', type=int, default=1, help='applied stride') - parser.add_argument('--window_size', dest='window_size', type=int, default=64, help='size of resulting patches') - parser.add_argument('--bg_thresh', dest='bg_thresh', type=float, default=0, help='skip patches without information using a treshold') - parser.add_argument('--limit_slices', dest='limit_slices', type=bool, default=False, help='limit amount of slices') - parser.add_argument('--n_thresh', dest='n_thresh', type=int, default=5000, help='amount of slices') - parser.add_argument('--seed', dest='seed', type=int, default=None, help='seed for random choice of limited slices') + parser.add_argument('input_file', type=argparse.FileType('r'), help='Input file') + parser.add_argument('out_folder', help='Output directory') + parser.add_argument('--stride', dest='stride', type=int, default=1, help='Applied stride') + parser.add_argument('--window_size', dest='window_size', type=int, default=64, help='Size of resulting patches') + parser.add_argument('--bg_thresh', dest='bg_thresh', type=float, default=0, help='Skip background patches without information using a treshold') + parser.add_argument('--n_thresh', dest='n_thresh', type=int, default=5000, help='Maximum number of slices to retain') + parser.add_argument('--seed', dest='seed', type=int, default=None, help='Seed for random choice of slices') args = parser.parse_args() - slice_image(args.input_file.name, args.out_folder, - label=args.label_file, label_out_folder=args.label_out_folder, - stride=args.stride, window_size=args.window_size, bg_thresh=args.bg_thresh, - limit_slices=args.limit_slices, n_thresh=args.n_thresh, seed=args.seed) + slice_image( + args.input_file.name, + args.out_folder, + stride=args.stride, + window_size=args.window_size, + bg_thresh=args.bg_thresh, + limit_slices=args.n_thresh > 0, + n_thresh=args.n_thresh, + seed=args.seed, + )
--- a/slice_image.xml Mon Nov 13 22:12:22 2023 +0000 +++ b/slice_image.xml Thu Apr 04 15:26:38 2024 +0000 @@ -1,5 +1,12 @@ -<tool id="ip_slice_image" name="Slice image" version="0.3-2"> +<tool id="ip_slice_image" name="Slice image into patches" version="0.3-3"> <description></description> + <macros> + <import>creators.xml</import> + <import>tests.xml</import> + </macros> + <creator> + <expand macro="creators/bmcv" /> + </creator> <edam_operations> <edam_operation>operation_3443</edam_operation> </edam_operations> @@ -12,34 +19,35 @@ <requirement type="package" version="1.1.0">scipy</requirement> <requirement type="package" version="0.15.1">tifffile</requirement> </requirements> - <command detect_errors="aggressive"> - <![CDATA[ + <command detect_errors="aggressive"><![CDATA[ + mkdir ./out && + python '$__tool_directory__/slice_image.py' '$input_file' ./out - --stride $stride --window_size $patch_size --bg_thresh $bg_thresh - --limit_slices $limit_slices - #if $limit_slices: - --n_thresh $n_thresh + + --stride '$stride' + --window_size '$patch_size' + --bg_thresh '$bg_thresh' + + #if $n_thresh > 0: + --n_thresh '$n_thresh' #end if - #if $control_rng: - --seed $seed + + #if len('$seed') > 0: + --seed '$seed' #end if + && ls -l ./out - ]]> - </command> + + ]]></command> <inputs> - <param name="input_file" type="data" format="tiff,png,jpg,bmp" label="Input image"/> - <!--<param name="out_folder" type="text" label="Output folder for image slices"/> - <param name="label_file" type="data" format="tiff,png,jpg,bmp" label="Auxiliary label file to split in the same way"/>--> - <param name="stride" type="integer" optional="true" value="16"/> - <param name="patch_size" type="integer" optional="true" value="64" label="Size of resulting (quadratic-shaped) slices"/> - <param name="bg_thresh" type="float" optional="true" value="0" label="Threshold to not be considered background"/> - <param name="limit_slices" type="boolean" checked="true" label="Should the number of slices be limited?"/> - <param name="n_thresh" type="integer" optional="true" label="Maximum amount of slices; only needed if limit_slices is selected"/> - <param name="control_rng" type="boolean" checked="false" label="Boolean that controls if a certain seed should be selected for the random number generator"/> - <param name="seed" type="integer" value="1" - label="Seed chosen for the random number generator of the random choice of limited slices. Only required if cotrol_rng is selected"/> + <param name="input_file" type="data" format="tiff,png" label="Input image"/> + <param name="stride" type="integer" optional="true" value="16" min="1" label="Stride" help="Minimum offset between any two patches in pixels."/> + <param name="patch_size" type="integer" optional="true" value="64" label="Patch size" help="Width of the patches in pixels (the height is identical)."/> + <param name="bg_thresh" type="float" optional="true" value="0" min="0" label="Maximum patch homogeneity" help="If larger than 0, patches with a homogeneity above this threshold will be considered as purely background and discarded."/> + <param name="n_thresh" type="integer" optional="true" label="Maximum number of patches" value="0" min="0" help="If larger than 0, only the specified number of patches will be retained (or less). Those will be selected randomly."/> + <param name="seed" type="hidden" value=""/> </inputs> <outputs> <collection name="slices" type="list" label="Slices obtained from input"> @@ -47,25 +55,38 @@ </collection> </outputs> <tests> + <!-- Tests for TIFF input --> <test> <param name="input_file" value="input.tiff"/> - <param name="limit_slices" value="true"/> <param name="n_thresh" value="5"/> - <param name="control_rng" value="true"/> <param name="seed" value="17"/> <output_collection name="slices" type="list"> - <element name="148.tiff" file="input_148.tiff" ftype="tiff" compare="sim_size"/> - <element name="155.tiff" file="input_155.tiff" ftype="tiff" compare="sim_size"/> - <element name="187.tiff" file="input_187.tiff" ftype="tiff" compare="sim_size"/> - <element name="212.tiff" file="input_212.tiff" ftype="tiff" compare="sim_size"/> - <element name="267.tiff" file="input_267.tiff" ftype="tiff" compare="sim_size"/> + <expand macro="tests/intensity_image_diff/element" name="148.tiff" value="input_148.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="155.tiff" value="input_155.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="187.tiff" value="input_187.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="212.tiff" value="input_212.tiff" ftype="tiff"/> + <expand macro="tests/intensity_image_diff/element" name="267.tiff" value="input_267.tiff" ftype="tiff"/> </output_collection> </test> + <!-- TODO: Add tests for PNG input --> </tests> <help> - **What it does** + + **Slices an image into multiple smaller, square-shaped patches.** + + For overlapping patches, set the stride to a value smaller than the patch size. + For non-overlapping patches, set the stride to a value identical to the patch size (or larger). + If the stride is set to a value larger than the patch size, parts of the original image will be skipped. - Slices image into multiple smaller patches. + Optionally, patches entirely corresponding to image background are discarded. + To decide whether a patch corresponds to image background, the `homogeneity`_ of its `gray-level co-occurrence matrix`_ is considered. + + .. _homogeneity: https://scikit-image.org/docs/stable/api/skimage.feature.html#skimage.feature.graycoprops + .. _gray-level co-occurrence matrix: https://scikit-image.org/docs/stable/api/skimage.feature.html#skimage.feature.graycomatrix + + In addition, the number of the remaining patches can be reduced by specifying a maximum number of patches to retain. + Those will be selected randomly. + </help> <citations> <citation type="doi">10.1016/j.jbiotec.2017.07.019</citation>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests.xml Thu Apr 04 15:26:38 2024 +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>