Mercurial > repos > imgteam > 2d_simple_filter
changeset 3:6c4b22ef2b81 draft
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/2d_simple_filter/ commit c045f067a57e8308308cf6329060c7ccd3fc372f
author | imgteam |
---|---|
date | Thu, 04 Apr 2024 15:23:42 +0000 |
parents | f70b215d155c |
children | d51310ab328a |
files | creators.xml filter.xml filter_image.py test-data/input1_gaussian.tif test-data/input1_median.tif test-data/input1_prewitt_h.tif test-data/input1_prewitt_v.tif test-data/input1_sobel_h.tif test-data/input1_sobel_v.tif test-data/input1_uint8.tif test-data/input2_float.tif test-data/input2_gaussian.tif test-data/res.tif test-data/sample.tif tests.xml |
diffstat | 15 files changed, 249 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/creators.xml Thu Apr 04 15:23:42 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/filter.xml Fri Nov 10 13:44:57 2023 +0000 +++ b/filter.xml Thu Apr 04 15:23:42 2024 +0000 @@ -1,49 +1,135 @@ -<tool id="ip_filter_standard" name="Filter 2D image" version="0.0.3-3"> - <description>with scikit-image</description> +<tool id="ip_filter_standard" name="Filter 2-D image" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.05"> + <description>with scipy</description> + <macros> + <import>creators.xml</import> + <import>tests.xml</import> + <token name="@TOOL_VERSION@">1.12.0</token> + <token name="@VERSION_SUFFIX@">0</token> + </macros> + <creator> + <expand macro="creators/bmcv" /> + </creator> <edam_operations> <edam_operation>operation_3443</edam_operation> </edam_operations> <xrefs> - <xref type="bio.tools">scikit-image</xref> - <xref type="biii">scikit-image</xref> + <xref type="biii">scipy</xref> </xrefs> <requirements> - <requirement type="package" version="0.14.2">scikit-image</requirement> - <requirement type="package" version="1.15.4">numpy</requirement> - <requirement type="package" version="5.3.0">pillow</requirement> - <requirement type="package" version="0.15.1">tifffile</requirement> + <requirement type="package" version="@TOOL_VERSION@">scipy</requirement> + <requirement type="package" version="1.26.4">numpy</requirement> + <requirement type="package" version="0.22.0">scikit-image</requirement> + <requirement type="package" version="2024.2.12">tifffile</requirement> </requirements> - <command detect_errors="aggressive"> - <![CDATA[ - python '$__tool_directory__/filter_image.py' '$input' '$output' $filter_type $radius - ]]> - </command> + <command detect_errors="aggressive"><![CDATA[ + + python '$__tool_directory__/filter_image.py' + + '$input' + '$output' + + $filter_type + $size + + ]]></command> <inputs> - <param name="filter_type" type="select" label="Filter type"> - <option value="median" selected="True">Median</option> - <option value="gaussian">Gaussian Blur</option> - <option value="prewitt">Prewitt</option> - <option value="sobel">Sobel</option> - <option value="scharr">Scharr</option> - </param> - <param name="radius" type="integer" value="3" label="Radius/Sigma" /> - <param name="input" type="data" format="tiff" label="Source file" /> + <param name="input" type="data" format="tiff,png" label="Input image" /> + <conditional name="filter"> + <param name="filter_type" type="select" label="Filter type"> + <option value="gaussian" selected="True">Gaussian</option> + <option value="median">Median</option> + <option value="prewitt_h">Prewitt horizontal</option> + <option value="prewitt_v">Prewitt vertical</option> + <option value="sobel_h">Sobel horizontal</option> + <option value="sobel_v">Sobel vertical</option> + </param> + <when value="gaussian"> + <param name="size" type="float" value="3" min="0.1" label="Sigma" help="The half width of the Gaussian bell (in pixels)." /> + </when> + <when value="median"> + <param name="size" type="integer" value="3" label="Radius" help="Radius of the neighborhood (in pixels)." /> + </when> + <when value="prewitt_h"> + <param name="size" type="hidden" value="0" /> + </when> + <when value="prewitt_v"> + <param name="size" type="hidden" value="0" /> + </when> + <when value="sobel_h"> + <param name="size" type="hidden" value="0" /> + </when> + <when value="sobel_v"> + <param name="size" type="hidden" value="0" /> + </when> + </conditional> </inputs> <outputs> <data format="tiff" name="output" /> </outputs> <tests> - <test> - <param name="input" value="sample.tif" /> - <output name="output" value="res.tif" ftype="tiff" compare="sim_size"/> - <param name="filter_type" value="prewitt" /> - <param name="radius" value="4" /> - </test> + <!-- Tests with uint8 TIFF input image --> + <test> + <param name="input" value="input1_uint8.tif" /> + <param name="filter_type" value="gaussian" /> + <expand macro="tests/intensity_image_diff" name="output" value="input1_gaussian.tif" ftype="tiff"> + <!-- + + The input file `input1_uint8.tif` has values ranging between 23 and 254, with a mean value of 63.67. + + Below, we use an assertion in addition to the `image_diff` comparison, to ensure that the range of + values is preserved. The motiviation behind this is that the expectation images are usually checked + visually, which means that the `image_diff` comparison is likely to ensure that the brightness of + the image is correct, thus it's good to double-check the range of values (hence the comparably large + value for `eps`). This also concerns the median filter. + + --> + <has_image_mean_intensity mean_intensity="63.67" eps="10"/> + </expand> + </test> + <test> + <param name="input" value="input1_uint8.tif" /> + <param name="filter_type" value="median" /> + <expand macro="tests/intensity_image_diff" name="output" value="input1_median.tif" ftype="tiff"> + <!-- See note for Gaussian filter above. --> + <has_image_mean_intensity mean_intensity="63.67" eps="10"/> + </expand> + </test> + <test> + <param name="input" value="input1_uint8.tif" /> + <param name="filter_type" value="prewitt_h" /> + <expand macro="tests/intensity_image_diff" name="output" value="input1_prewitt_h.tif" ftype="tiff"/> + </test> + <test> + <param name="input" value="input1_uint8.tif" /> + <param name="filter_type" value="prewitt_v" /> + <expand macro="tests/intensity_image_diff" name="output" value="input1_prewitt_v.tif" ftype="tiff"/> + </test> + <test> + <param name="input" value="input1_uint8.tif" /> + <param name="filter_type" value="sobel_h" /> + <expand macro="tests/intensity_image_diff" name="output" value="input1_sobel_h.tif" ftype="tiff"/> + </test> + <test> + <param name="input" value="input1_uint8.tif" /> + <param name="filter_type" value="sobel_v" /> + <expand macro="tests/intensity_image_diff" name="output" value="input1_sobel_v.tif" ftype="tiff"/> + </test> + <!-- Tests with float TIFF input image --> + <test> + <param name="input" value="input2_float.tif" /> + <param name="filter_type" value="gaussian" /> + <expand macro="tests/intensity_image_diff" name="output" value="input2_gaussian.tif" ftype="tiff"> + <!-- See note for Gaussian filter above. --> + <has_image_mean_intensity mean_intensity="0.25" eps="0.01"/> + </expand> + </test> </tests> <help> - **What it does** + + **Applies a standard filter to a single-channel 2-D image.** - Applies a standard filter to an image. + Mean filters like the Gaussian filter or the median filter preserve both the brightness of the image, and the range of values. + </help> <citations> <citation type="doi">10.1016/j.jbiotec.2017.07.019</citation>
--- a/filter_image.py Fri Nov 10 13:44:57 2023 +0000 +++ b/filter_image.py Thu Apr 04 15:23:42 2024 +0000 @@ -1,29 +1,28 @@ import argparse -import sys -import skimage.filters +import scipy.ndimage as ndi import skimage.io import skimage.util -from skimage import img_as_uint from skimage.morphology import disk -filterOptions = { - 'median': lambda img_raw, radius: skimage.filters.median(img_raw, disk(radius)), - 'gaussian': lambda img_raw, radius: skimage.filters.gaussian(img_raw, sigma=radius), - 'prewitt': lambda img_raw, radius: skimage.filters.prewitt(img_raw), - 'sobel': lambda img_raw, radius: skimage.filters.sobel(img_raw), - 'scharr': lambda img_raw, radius: skimage.filters.scharr(img_raw), +filters = { + 'gaussian': lambda im, sigma: ndi.gaussian_filter(im, sigma), + 'median': lambda im, radius: ndi.median_filter(im, footprint=disk(radius)), + 'prewitt_h': lambda im, *args: ndi.prewitt(im, axis=1), + 'prewitt_v': lambda im, *args: ndi.prewitt(im, axis=0), + 'sobel_h': lambda im, *args: ndi.sobel(im, axis=1), + 'sobel_v': lambda im, *args: ndi.sobel(im, axis=0), } if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument('input_file', type=argparse.FileType('r'), default=sys.stdin, help='input file') - parser.add_argument('out_file', type=argparse.FileType('w'), default=sys.stdin, help='out file (TIFF)') - parser.add_argument('filter_type', choices=filterOptions.keys(), help='conversion type') - parser.add_argument('radius', default=3.0, type=float, help='Radius/Sigma') + parser.add_argument('input', type=argparse.FileType('r'), help='Input file') + parser.add_argument('output', type=argparse.FileType('w'), help='Output file (TIFF)') + parser.add_argument('filter', choices=filters.keys(), help='Filter to be used') + parser.add_argument('size', type=float, help='Size of the filter (e.g., radius, sigma)') args = parser.parse_args() - img_in = skimage.io.imread(args.input_file.name) - res = img_as_uint(filterOptions[args.filter_type](img_in, args.radius)) - skimage.io.imsave(args.out_file.name, res, plugin='tifffile') + im = skimage.io.imread(args.input.name) + res = filters[args.filter](im, args.size) + skimage.io.imsave(args.output.name, res, plugin='tifffile')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests.xml Thu Apr 04 15:23:42 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>