comparison filter.xml @ 4:5ab62693dca5 draft default tip

planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/2d_simple_filter/ commit c9cc62c508da3804872d105800993746c36cca48
author imgteam
date Sat, 20 Dec 2025 18:28:21 +0000
parents 53c55776a974
children
comparison
equal deleted inserted replaced
3:53c55776a974 4:5ab62693dca5
1 <tool id="ip_filter_standard" name="Apply 2-D image filter" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.05"> 1 <tool id="ip_filter_standard" name="Apply standard image filter" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.05">
2 <description>with scipy</description> 2 <description>with scipy</description>
3 <macros> 3 <macros>
4 <!--
5 === BEGIN OF MACROS ===
6 -->
4 <import>creators.xml</import> 7 <import>creators.xml</import>
5 <import>tests.xml</import> 8 <import>tests.xml</import>
6 <token name="@TOOL_VERSION@">1.16.3</token> 9 <token name="@TOOL_VERSION@">1.16.3</token>
7 <token name="@VERSION_SUFFIX@">0</token> 10 <token name="@VERSION_SUFFIX@">1</token>
8 <xml name="select_axis"> 11 <!--
9 <param name="axis" type="select" label="Direction"> 12 === MACROS: UI text tokens ===
10 <option value="1" selected="true">Horizontal</option> 13 -->
11 <option value="0">Vertical</option> 14 <token name="@DEFAULT_AXIS_LABEL@">Direction</token>
15 <token name="@DERIVATIVE_AXIS_LABEL@">Direction of the derivative</token>
16 <token name="@DERIVATIVE_AXIS_HELP@">The axis to compute the derivative along.</token>
17 <token name="@PREWITT_AXIS_HELP@">
18 The Prewitt filter is a 2-D image filter that computes an approximation of the derivative of the image intensities in the given direction.
19 </token>
20 <token name="@SOBEL_AXIS_HELP@">
21 The Sobel filter is a 2-D image filter that computes an approximation of the derivative of the image intensities in the given direction.
22 </token>
23 <!--
24 === MACROS: Direction selectors ===
25 -->
26 <xml name="select_direction" tokens="axis1,axis2,axis1_label,axis2_label,label,help"
27 token_axis1="1" token_axis1_label="Horizontal" token_axis2="0" token_axis2_label="Vertical" token_label="@DEFAULT_AXIS_LABEL@" token_help="">
28 <param name="direction" type="select" label="@LABEL@" help="@HELP@">
29 <option value="@AXIS1@" selected="true">@AXIS1_LABEL@</option>
30 <option value="@AXIS2@">@AXIS2_LABEL@</option>
31 <yield/>
12 </param> 32 </param>
13 </xml> 33 </xml>
34 <xml name="select_direction_3d" tokens="label,help" token_label="@DEFAULT_AXIS_LABEL@" token_help="">
35 <!-- Normalized axes layout for 3-D images: ZYX -->
36 <expand macro="select_direction" axis1="2" axis1_label="Horizontal" axis2="1" axis2_label="Vertical" label="@LABEL@" help="@HELP@">
37 <option value="0">Orthogonal</option>
38 </expand>
39 </xml>
40 <!--
41 === MACROS: Groups of fields for 3-D processing setup ===
42 -->
43 <xml name="select_axes_2d" tokens="yx_selected" token_yx_selected="true">
44 <param name="axes" type="select" label="Processing of 3-D images"
45 help="This governs which axes are processed jointly.">
46 <yield/>
47 <option value="YX" selected="@YX_SELECTED@">Perform 2-D filtering of all XY-slices</option>
48 <option value="YZ">Perform 2-D filtering of all YZ-slices</option>
49 <option value="XZ">Perform 2-D filtering of all XZ-slices</option>
50 </param>
51 </xml>
52 <xml name="select_axes_2d_or_3d">
53 <expand macro="select_axes_2d" yx_selected="false">
54 <option value="ZYX" selected="true">Perform 3-D filtering</option>
55 </expand>
56 </xml>
57 <xml name="directed_3d" tokens="selector,axis_label,axis_help"
58 token_selector="select_axes_2d" token_axis_label="@DEFAULT_AXIS_LABEL@" token_axis_help="">
59 <conditional name="directed_3d">
60 <expand macro="@SELECTOR@"/>
61 <yield/>
62 <when value="YX">
63 <expand macro="select_direction" label="@AXIS_LABEL@" help="@AXIS_HELP@"/>
64 </when>
65 <when value="YZ">
66 <expand macro="select_direction" label="@AXIS_LABEL@" help="@AXIS_HELP@"
67 axis1="0" axis1_label="Vertical" axis2="1" axis2_label="Orthogonal"/>
68 </when>
69 <when value="XZ">
70 <expand macro="select_direction" label="@AXIS_LABEL@" help="@AXIS_HELP@"
71 axis1="0" axis1_label="Horizontal" axis2="1" axis2_label="Orthogonal"/>
72 </when>
73 </conditional>
74 </xml>
75 <xml name="directed_3d_full" tokens="axis_label,axis_help"
76 token_axis_label="@DEFAULT_AXIS_LABEL@" token_axis_help="">
77 <expand macro="directed_3d" selector="select_axes_2d_or_3d">
78 <when value="ZYX">
79 <expand macro="select_direction_3d" label="@AXIS_LABEL@" help="@AXIS_HELP@"/>
80 </when>
81 </expand>
82 </xml>
83 <!--
84 === MACROS: Field for optional anisotropic filtering ===
85 -->
86 <xml name="anisotropic" tokens="entities" token_entities="pixels/voxels">
87 <param name="anisotropic" type="boolean" checked="true" label="Anisotropic filtering"
88 help="Perform anisotropic filtering if the image @ENTITIES@ are anistropic. Has no effect if the @ENTITIES@ are isotropic or no information about the size of the @ENTITIES@ is available from the matadata of the image."/>
89 </xml>
90 <!--
91 === MACROS: Group of fields for filter setup ===
92 -->
93 <xml name="filter" tokens="entities" token_entities="pixels/voxels">
94 <conditional name="filter">
95 <param name="filter_type" type="select" label="Filter type"
96 help="Gaussian filters include smoothing filters for pre-processing (denoising, scale selection) and Gaussian derivatives for edge and feature detection. Box filters use uniform rectangular averaging. Median filters remove impulse noise and suit binary images and label maps. Prewitt and Sobel filters compute first-order derivatives, with Sobel providing better isotropy.">
97 <option value="gaussian" selected="True">Gaussian</option>
98 <option value="uniform">Box filter</option>
99 <option value="median">Median</option>
100 <option value="prewitt">Prewitt</option>
101 <option value="sobel">Sobel</option>
102 </param>
103 <when value="gaussian">
104 <param name="sigma" type="float" value="3" min="0.1" label="Sigma"
105 help="The half width of the Gaussian bell (in pixels)."/>
106 <expand macro="anisotropic" entities="@ENTITIES@"/>
107 <conditional name="derivative">
108 <param name="order" type="select" label="Advanced kernel options"
109 help="Kernels based on the Gaussian bell are low-pass filters. Kernels based on the 1st-order and 2nd-order derivative act like high-pass and band-pass filters, respectively.">
110 <option value="0">No derivative (Gaussian bell)</option>
111 <option value="1">1st-order derivative of the Gaussian bell</option>
112 <option value="2">2nd-order derivative of the Gaussian bell</option>
113 </param>
114 <when value="0">
115 <yield name="gaussian_order0"/>
116 </when>
117 <when value="1">
118 <yield name="gaussian_order1"/>
119 </when>
120 <when value="2">
121 <yield name="gaussian_order2"/>
122 </when>
123 </conditional>
124 </when>
125 <when value="uniform">
126 <param name="size" type="integer" min="2" value="3" label="Size"
127 help="Edge length of the neighborhood (square, in pixels)."/>
128 <expand macro="anisotropic" entities="@ENTITIES@"/>
129 <yield name="uniform"/>
130 </when>
131 <when value="median">
132 <param name="size" type="integer" min="2" value="3" label="Size"
133 help="Edge length of the neighborhood (square, in pixels)."/>
134 <expand macro="anisotropic" entities="@ENTITIES@"/>
135 <yield name="median"/>
136 </when>
137 <when value="prewitt">
138 <yield name="prewitt"/>
139 </when>
140 <when value="sobel">
141 <yield name="sobel"/>
142 </when>
143 </conditional>
144 </xml>
145 <xml name="select_dtype">
146 <param name="dtype" type="select" label="Output pixel type"
147 help="Data type used to store the pixel values in the output image.">
148 <option value="floating" selected="True">Same as the input image (if floating point, and 64-bit floating point otherwise)</option>
149 <option value="float64">64-bit floating point</option>
150 <option value="float32">32-bit floating point</option>
151 <option value="float16">16-bit floating point</option>
152 </param>
153 </xml>
154 <!--
155 === END OF MACROS ===
156 -->
14 </macros> 157 </macros>
15 <creator> 158 <creator>
16 <expand macro="creators/bmcv"/> 159 <expand macro="creators/bmcv"/>
17 <expand macro="creators/kostrykin"/> 160 <expand macro="creators/kostrykin"/>
18 </creator> 161 </creator>
24 <xref type="biii">scipy</xref> 167 <xref type="biii">scipy</xref>
25 </xrefs> 168 </xrefs>
26 <requirements> 169 <requirements>
27 <requirement type="package" version="@TOOL_VERSION@">scipy</requirement> 170 <requirement type="package" version="@TOOL_VERSION@">scipy</requirement>
28 <requirement type="package" version="2.3.5">numpy</requirement> 171 <requirement type="package" version="2.3.5">numpy</requirement>
29 <requirement type="package" version="0.25.2">scikit-image</requirement> 172 <requirement type="package" version="0.12.2">ome-zarr</requirement>
30 <requirement type="package" version="2025.10.16">tifffile</requirement> 173 <requirement type="package" version="2025.10.16">tifffile</requirement>
31 <requirement type="package" version="0.5.2">giatools</requirement> 174 <requirement type="package" version="0.6.0">giatools</requirement>
32 </requirements> 175 </requirements>
176 <required_files>
177 <include type="literal" path="filter.py"/>
178 </required_files>
33 <command detect_errors="aggressive"><![CDATA[ 179 <command detect_errors="aggressive"><![CDATA[
34 180
35 python '$__tool_directory__/filter.py' 181 python '$__tool_directory__/filter.py'
36 182
37 '$input' 183 #if $input.extension == "zarr"
184 '$setup.input.extra_files_path/$setup.input.metadata.store_root'
185 #else
186 '$setup.input'
187 #end if
188
38 '$output' 189 '$output'
39 '$params' 190 '$params'
40 191
41 ]]></command> 192 ]]></command>
42 <configfiles> 193 <configfiles>
43 <configfile name="params"><![CDATA[ 194 <configfile name="params"><![CDATA[
44 { 195 {
45 196
46 ## ===================================================================== 197 ## =================================================================================
47 #if $filter.filter_type == "gaussian" 198 #if $setup.filter.filter_type == "gaussian"
48 "sigma": $filter.sigma, 199 "sigma": $setup.filter.sigma,
49 "order": $filter.derivative.order, 200 "order": $setup.filter.derivative.order,
50 201 "anisotropic": $setup.filter.anisotropic,
51 #if $filter.derivative.order != "0" 202
52 "axis": $filter.derivative.axis, 203 #if $setup.target == "2d"
204 #if $setup.filter.derivative.order != "0"
205 "direction": $setup.filter.derivative.direction,
206 "dtype": "$setup.filter.derivative.dtype",
207 #end if
208 #else
209 #if $setup.filter.derivative.order == "0"
210 "axes": "$setup.filter.derivative.axes",
211 #else
212 "axes": "$setup.filter.derivative.directed_3d.axes",
213 "direction": $setup.filter.derivative.directed_3d.direction,
214 "dtype": "$setup.filter.derivative.dtype",
215 #end if
53 #end if 216 #end if
54 217
55 ## ===================================================================== 218 ## =================================================================================
56 #elif $filter.filter_type == "uniform" 219 #elif $setup.filter.filter_type == "uniform"
57 "size": $filter.size, 220 "size": $setup.filter.size,
58 221 "anisotropic": $setup.filter.anisotropic,
59 ## ===================================================================== 222
60 #elif $filter.filter_type == "median" 223 #if $setup.target == "3d"
61 "radius": $filter.radius, 224 "axes": "$setup.filter.axes",
62 225 #end if
63 ## ===================================================================== 226
64 #elif $filter.filter_type == "prewitt" or $filter.filter_type == "sobel" 227 ## =================================================================================
65 "axis": $filter.axis, 228 #elif $setup.filter.filter_type == "median"
66 229 "size": $setup.filter.size,
67 ## ===================================================================== 230 "anisotropic": $setup.filter.anisotropic,
231
232 #if $setup.target == "3d"
233 "axes": "$setup.filter.axes",
234 #end if
235
236 ## =================================================================================
237 #elif $setup.filter.filter_type == "prewitt" or $setup.filter.filter_type == "sobel"
238
239 #if $setup.target == "2d"
240 "direction": $setup.filter.direction,
241 "dtype": "$setup.filter.dtype",
242 #else
243 "axes": "$setup.filter.directed_3d.axes",
244 "direction": $setup.filter.directed_3d.direction,
245 "dtype": "$setup.filter.dtype",
246 #end if
247
248 ## =================================================================================
68 #end if 249 #end if
69 250
70 "filter_type": "$filter.filter_type" 251 "filter_type": "$setup.filter.filter_type"
71 252
72 } 253 }
73 ]]></configfile> 254 ]]></configfile>
74 </configfiles> 255 </configfiles>
75 <inputs> 256 <inputs>
76 <param name="input" type="data" format="tiff,png" label="Input image"/> 257 <conditional name="setup">
77 <conditional name="filter"> 258 <param name="target" type="select" label="Type of image data to process"
78 <param name="filter_type" type="select" label="Filter type"> 259 help='Select "2-D image data" or "3-D image data" if you want to filter 2-D images or 3-D images, respectively, or series thereof (e.g., stacks or hyperstacks, such as temporal image sequences).'>
79 <option value="gaussian" selected="True">Gaussian</option> 260 <option value="2d" selected="true">2-D image data (or series thereof)</option>
80 <option value="uniform">Box filter (uniform filter)</option> 261 <option value="3d">3-D image data (or series thereof)</option>
81 <option value="median">Median</option>
82 <option value="prewitt">Prewitt</option>
83 <option value="sobel">Sobel</option>
84 </param> 262 </param>
85 <when value="gaussian"> 263 <!-- Processing 2-D image data -->
86 <param name="sigma" type="float" value="3" min="0.1" label="Sigma" 264 <when value="2d">
87 help="The half width of the Gaussian bell (in pixels)."/> 265 <param name="input" type="data" format="tiff,zarr,png,jpg" label="Input image (2-D)">
88 <conditional name="derivative"> 266 <!--
89 <param name="order" type="select" label="Use a derivative?"> 267 The OME-Zarr datatype in Galaxy is currently not derived from the Image datatype, and it does
90 <option value="0">No derivative (mean filter)</option> 268 hence not inherit the metadata fields like `depth`. To cope with that, we allow all datasets
91 <option value="1">1st-order derivative</option> 269 for 2-D processing except those which are *known* to be 3-D.
92 <option value="2">2nd-order derivative</option> 270 -->
93 </param> 271 <validator type="expression" message="Dataset is not a 2-D image"
94 <when value="0"> 272 ><![CDATA[getattr(value.metadata, "depth", None) in (None, '') or int(value.metadata.depth) < 2]]></validator>
95 </when> 273 </param>
96 <when value="1"> 274 <expand macro="filter" entities="pixels">
97 <expand macro="select_axis"/> 275 <token name="gaussian_order1">
98 </when> 276 <expand macro="select_direction" label="@DERIVATIVE_AXIS_LABEL@" help="@DERIVATIVE_AXIS_HELP@"/>
99 <when value="2"> 277 <expand macro="select_dtype"/>
100 <expand macro="select_axis"/> 278 </token>
101 </when> 279 <token name="gaussian_order2">
102 </conditional> 280 <expand macro="select_direction" label="@DERIVATIVE_AXIS_LABEL@" help="@DERIVATIVE_AXIS_HELP@"/>
281 <expand macro="select_dtype"/>
282 </token>
283 <token name="prewitt">
284 <expand macro="select_direction" label="@DERIVATIVE_AXIS_LABEL@" help="@PREWITT_AXIS_HELP@"/>
285 <expand macro="select_dtype"/>
286 </token>
287 <token name="sobel">
288 <expand macro="select_direction" label="@DERIVATIVE_AXIS_LABEL@" help="@SOBEL_AXIS_HELP@"/>
289 <expand macro="select_dtype"/>
290 </token>
291 </expand>
103 </when> 292 </when>
104 <when value="uniform"> 293 <!-- Processing 3-D image data -->
105 <param name="size" type="integer" min="2" value="3" label="Size" 294 <when value="3d">
106 help="Edge length of the neighborhood (square, in pixels)."/> 295 <param name="input" type="data" format="tiff,zarr" label="Input image (3-D)">
107 </when> 296 <!--
108 <when value="median"> 297 The OME-Zarr datatype in Galaxy is currently not derived from the Image datatype, and it does
109 <param name="radius" type="integer" min="2" value="3" label="Radius" 298 hence not inherit the metadata fields like `depth`. To cope with that, we allow all datasets
110 help="Radius of the neighborhood (circle, in pixels)." /> 299 for 3-D processing except those which are *known* to be 2-D.
111 </when> 300 -->
112 <when value="prewitt"> 301 <validator type="expression" message="Dataset is not a 3-D image"
113 <expand macro="select_axis"/> 302 ><![CDATA[getattr(value.metadata, "depth", None) in (None, '') or int(value.metadata.depth) >= 2]]></validator>
114 </when> 303 </param>
115 <when value="sobel"> 304 <expand macro="filter" entities="voxels">
116 <expand macro="select_axis"/> 305 <token name="gaussian_order0">
306 <expand macro="select_axes_2d_or_3d"/>
307 </token>
308 <token name="gaussian_order1">
309 <expand macro="select_dtype"/>
310 <expand macro="directed_3d_full" axis_label="@DERIVATIVE_AXIS_LABEL@" axis_help="@DERIVATIVE_AXIS_HELP@"/>
311 </token>
312 <token name="gaussian_order2">
313 <expand macro="select_dtype"/>
314 <expand macro="directed_3d_full" axis_label="@DERIVATIVE_AXIS_LABEL@" axis_help="@DERIVATIVE_AXIS_HELP@"/>
315 </token>
316 <token name="uniform">
317 <expand macro="select_axes_2d_or_3d"/>
318 </token>
319 <token name="median">
320 <expand macro="select_axes_2d_or_3d"/>
321 </token>
322 <token name="prewitt">
323 <expand macro="select_dtype"/>
324 <expand macro="directed_3d" axis_label="@DERIVATIVE_AXIS_LABEL@" axis_help="@PREWITT_AXIS_HELP@"/>
325 </token>
326 <token name="sobel">
327 <expand macro="select_dtype"/>
328 <expand macro="directed_3d" axis_label="@DERIVATIVE_AXIS_LABEL@" axis_help="@SOBEL_AXIS_HELP@"/>
329 </token>
330 </expand>
117 </when> 331 </when>
118 </conditional> 332 </conditional>
119 </inputs> 333 </inputs>
120 <outputs> 334 <outputs>
121 <data format="tiff" name="output"/> 335 <data format="tiff" name="output"/>
122 </outputs> 336 </outputs>
123 <tests> 337 <tests>
124 <!-- Tests with uint8 TIFF input image --> 338 <!--
125 <test> 339 =========================================================================================================
126 <param name="input" value="input1_uint8.tiff"/> 340 === TESTS: 2-D images
127 <conditional name="filter"> 341 =========================================================================================================
128 <param name="filter_type" value="gaussian"/> 342 -->
129 </conditional> 343 <test>
130 <expand macro="tests/intensity_image_diff" name="output" value="input1_gaussian.tiff" ftype="tiff"> 344 <!--
131 <!-- 345 Test 1: GAUSSIAN, range of values is preserved
132 346 ==============================================
133 The input file `input1_uint8.tiff` has values ranging between 23 and 254, with a mean value of 63.67. 347
134 348 The input file `input1_uint8.tiff` has values ranging between 23 and 254, with a mean value of 63.67.
135 Below, we use an assertion in addition to the `image_diff` comparison, to ensure that the range of 349
136 values is preserved. The motiviation behind this is that the expectation images are usually checked 350 Below, we use an assertion in addition to the `image_diff` comparison, to ensure that the range of
137 visually, which means that the `image_diff` comparison is likely to ensure that the brightness of 351 values is preserved. The motiviation behind this is that the expectation images are usually checked
138 the image is correct, thus it's good to double-check the range of values (hence the comparably large 352 visually, which means that the `image_diff` comparison is likely to ensure that the brightness of
139 value for `eps`). This also concerns the median filter. 353 the image is correct, thus it's good to double-check the range of values (hence the comparably large
140 354 value for `eps`). This also concerns the Median and Box filters (see below).
141 --> 355 -->
356 <conditional name="setup">
357 <param name="target" value="2d"/>
358 <param name="input" value="input/input1_uint8.tiff"/>
359 <conditional name="filter">
360 <param name="filter_type" value="gaussian"/>
361 </conditional>
362 </conditional>
363 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_gaussian.tiff" ftype="tiff">
364 <!-- Mean of Gaussian filter is approximately the mean intensity value of the image: -->
142 <has_image_mean_intensity mean_intensity="63.67" eps="10"/> 365 <has_image_mean_intensity mean_intensity="63.67" eps="10"/>
143 </expand> 366 </expand>
144 </test> 367 <assert_stdout>
145 <test> 368 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
146 <param name="input" value="input1_uint8.tiff"/> 369 <has_line line="Input image axes: QTZYXC"/>
147 <conditional name="filter"> 370 <has_line line="Input image dtype: uint8"/>
148 <param name="filter_type" value="median"/> 371 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=0, axes='YX'"/>
149 </conditional> 372 <has_line line="Output image shape: (265, 329)"/>
150 <expand macro="tests/intensity_image_diff" name="output" value="input1_median.tiff" ftype="tiff"> 373 <has_line line="Output image axes: YX"/>
151 <!-- See note for Gaussian filter above. --> 374 <has_line line="Output image dtype: uint8"/>
375 </assert_stdout>
376 </test>
377 <test>
378 <!--
379 Test 2: GAUSSIAN, test `sigma` parameter
380 ========================================
381 -->
382 <conditional name="setup">
383 <param name="target" value="2d"/>
384 <param name="input" value="input/input1_uint8.tiff"/>
385 <conditional name="filter">
386 <param name="filter_type" value="gaussian"/>
387 <param name="sigma" value="1.0"/>
388 </conditional>
389 </conditional>
390 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_gaussian_sigma1.tiff" ftype="tiff"/>
391 <assert_stdout>
392 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
393 <has_line line="Input image axes: QTZYXC"/>
394 <has_line line="Input image dtype: uint8"/>
395 <has_line line="Applying filter: gaussian_filter with sigma=1.0, order=0, axes='YX'"/>
396 <has_line line="Output image shape: (265, 329)"/>
397 <has_line line="Output image axes: YX"/>
398 <has_line line="Output image dtype: uint8"/>
399 </assert_stdout>
400 </test>
401 <test>
402 <!--
403 Test 3: GAUSSIAN, test data with anisotropic pixels
404 ===================================================
405 -->
406 <conditional name="setup">
407 <param name="target" value="2d"/>
408 <param name="input" value="input/input3_uint16.tiff"/>
409 <conditional name="filter">
410 <param name="filter_type" value="gaussian"/>
411 </conditional>
412 </conditional>
413 <expand macro="tests/intensity_image_diff" name="output" value="output/input3_gaussian.tiff" ftype="tiff"/>
414 <assert_stdout>
415 <has_line line="Input image shape: (1, 1, 1, 58, 64, 3)"/>
416 <has_line line="Input image axes: QTZYXC"/>
417 <has_line line="Input image dtype: uint16"/>
418 <has_line_matching expression="^Anisotropy of YX pixels/voxels: \(1\.414[0-9]+, 0\.707[0-9]+\)$"/>
419 <has_line_matching expression="^Applying filter: gaussian_filter with sigma=\(2\.121[0-9]+, 4\.242[0-9]+\), order=0, axes='YX'$"/>
420 <has_line line="Output image shape: (58, 64, 3)"/>
421 <has_line line="Output image axes: YXC"/>
422 <has_line line="Output image dtype: uint16"/>
423 </assert_stdout>
424 </test>
425 <test>
426 <!--
427 Test 4: GAUSSIAN, test data with anisotropic pixels and `"anisotropic": false`
428 ==============================================================================
429 -->
430 <conditional name="setup">
431 <param name="target" value="2d"/>
432 <param name="input" value="input/input3_uint16.tiff"/>
433 <conditional name="filter">
434 <param name="filter_type" value="gaussian"/>
435 <param name="anisotropic" value="false"/>
436 </conditional>
437 </conditional>
438 <expand macro="tests/intensity_image_diff" name="output" value="output/input3_gaussian_anisotropic-off.tiff" ftype="tiff"/>
439 <assert_stdout>
440 <has_line line="Input image shape: (1, 1, 1, 58, 64, 3)"/>
441 <has_line line="Input image axes: QTZYXC"/>
442 <has_line line="Input image dtype: uint16"/>
443 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=0, axes='YX'"/>
444 <has_line line="Output image shape: (58, 64, 3)"/>
445 <has_line line="Output image axes: YXC"/>
446 <has_line line="Output image dtype: uint16"/>
447 </assert_stdout>
448 </test>
449 <test>
450 <!--
451 Test 5: GAUSSIAN, test `"order": 1` (default is horizontal)
452 ===========================================================
453 -->
454 <conditional name="setup">
455 <param name="target" value="2d"/>
456 <param name="input" value="input/input1_uint8.tiff"/>
457 <conditional name="filter">
458 <param name="filter_type" value="gaussian"/>
459 <conditional name="derivative">
460 <param name="order" value="1"/>
461 </conditional>
462 </conditional>
463 </conditional>
464 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_gaussian_order1.tiff" ftype="tiff"/>
465 <assert_stdout>
466 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
467 <has_line line="Input image axes: QTZYXC"/>
468 <has_line line="Input image dtype: uint8"/>
469 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=(0, 1), axes='YX'"/>
470 <has_line line="Output image shape: (265, 329)"/>
471 <has_line line="Output image axes: YX"/>
472 <has_line line="Output image dtype: float64"/>
473 </assert_stdout>
474 </test>
475 <test>
476 <!--
477 Test 6: GAUSSIAN, test `"order": 1`, `"direction": 0` (vertical)
478 ================================================================
479 -->
480 <conditional name="setup">
481 <param name="target" value="2d"/>
482 <param name="input" value="input/input1_uint8.tiff"/>
483 <conditional name="filter">
484 <param name="filter_type" value="gaussian"/>
485 <conditional name="derivative">
486 <param name="order" value="1"/>
487 <param name="direction" value="0"/>
488 </conditional>
489 </conditional>
490 </conditional>
491 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_gaussian_order1_direction0.tiff" ftype="tiff"/>
492 <assert_stdout>
493 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
494 <has_line line="Input image axes: QTZYXC"/>
495 <has_line line="Input image dtype: uint8"/>
496 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=(1, 0), axes='YX'"/>
497 <has_line line="Output image shape: (265, 329)"/>
498 <has_line line="Output image axes: YX"/>
499 <has_line line="Output image dtype: float64"/>
500 </assert_stdout>
501 </test>
502 <test>
503 <!--
504 Test 7: GAUSSAIN, test `"order": 2`
505 ===================================
506 -->
507 <conditional name="setup">
508 <param name="target" value="2d"/>
509 <param name="input" value="input/input1_uint8.tiff"/>
510 <conditional name="filter">
511 <param name="filter_type" value="gaussian"/>
512 <conditional name="derivative">
513 <param name="order" value="2"/>
514 </conditional>
515 </conditional>
516 </conditional>
517 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_gaussian_order2.tiff" ftype="tiff"/>
518 <assert_stdout>
519 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
520 <has_line line="Input image axes: QTZYXC"/>
521 <has_line line="Input image dtype: uint8"/>
522 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=(0, 2), axes='YX'"/>
523 <has_line line="Output image shape: (265, 329)"/>
524 <has_line line="Output image axes: YX"/>
525 <has_line line="Output image dtype: float64"/>
526 </assert_stdout>
527 </test>
528 <test>
529 <!--
530 Test 8: BOX, range of values is preserved
531 =========================================
532
533 The input file `input1_uint8.tiff` has values ranging between 23 and 254, with a mean value of 63.67.
534
535 Below, we use an assertion in addition to the `image_diff` comparison, to ensure that the range of
536 values is preserved. The motiviation behind this is that the expectation images are usually checked
537 visually, which means that the `image_diff` comparison is likely to ensure that the brightness of
538 the image is correct, thus it's good to double-check the range of values (hence the comparably large
539 value for `eps`). This also concerns the Gaussian (see above) and Median filters (see below).
540 -->
541 <conditional name="setup">
542 <param name="target" value="2d"/>
543 <param name="input" value="input/input1_uint8.tiff"/>
544 <conditional name="filter">
545 <param name="filter_type" value="uniform"/>
546 </conditional>
547 </conditional>
548 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_uniform.tiff" ftype="tiff">
549 <!-- Mean of Box filter is approximately the mean intensity value of the image: -->
152 <has_image_mean_intensity mean_intensity="63.67" eps="10"/> 550 <has_image_mean_intensity mean_intensity="63.67" eps="10"/>
153 </expand> 551 </expand>
154 </test> 552 <assert_stdout>
155 <test> 553 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
156 <param name="input" value="input1_uint8.tiff"/> 554 <has_line line="Input image axes: QTZYXC"/>
157 <conditional name="filter"> 555 <has_line line="Input image dtype: uint8"/>
158 <param name="filter_type" value="prewitt"/> 556 <has_line line="Applying filter: uniform_filter with size=3, axes='YX'"/>
159 <param name="axis" value="1"/> 557 <has_line line="Output image shape: (265, 329)"/>
160 </conditional> 558 <has_line line="Output image axes: YX"/>
161 <expand macro="tests/intensity_image_diff" name="output" value="input1_prewitt_h.tiff" ftype="tiff"/> 559 <has_line line="Output image dtype: uint8"/>
162 </test> 560 </assert_stdout>
163 <test> 561 </test>
164 <param name="input" value="input1_uint8.tiff"/> 562 <test>
165 <conditional name="filter"> 563 <!--
166 <param name="filter_type" value="prewitt"/> 564 Test 9: BOX, test `size` parameter
167 <param name="axis" value="0"/> 565 ==================================
168 </conditional> 566 -->
169 <expand macro="tests/intensity_image_diff" name="output" value="input1_prewitt_v.tiff" ftype="tiff"/> 567 <conditional name="setup">
170 </test> 568 <param name="target" value="2d"/>
171 <test> 569 <param name="input" value="input/input1_uint8.tiff"/>
172 <param name="input" value="input1_uint8.tiff"/> 570 <conditional name="filter">
173 <conditional name="filter"> 571 <param name="filter_type" value="uniform"/>
174 <param name="filter_type" value="sobel"/> 572 <param name="size" value="5"/>
175 <param name="axis" value="1"/> 573 </conditional>
176 </conditional> 574 </conditional>
177 <expand macro="tests/intensity_image_diff" name="output" value="input1_sobel_h.tiff" ftype="tiff"/> 575 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_uniform_size5.tiff" ftype="tiff"/>
178 </test> 576 <assert_stdout>
179 <test> 577 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
180 <param name="input" value="input1_uint8.tiff"/> 578 <has_line line="Input image axes: QTZYXC"/>
181 <conditional name="filter"> 579 <has_line line="Input image dtype: uint8"/>
182 <param name="filter_type" value="sobel"/> 580 <has_line line="Applying filter: uniform_filter with size=5, axes='YX'"/>
183 <param name="axis" value="0"/> 581 <has_line line="Output image shape: (265, 329)"/>
184 </conditional> 582 <has_line line="Output image axes: YX"/>
185 <expand macro="tests/intensity_image_diff" name="output" value="input1_sobel_v.tiff" ftype="tiff"/> 583 <has_line line="Output image dtype: uint8"/>
186 </test> 584 </assert_stdout>
187 <!-- Tests with float TIFF input image --> 585 </test>
188 <test> 586 <test>
189 <param name="input" value="input2_float.tiff"/> 587 <!--
190 <conditional name="filter"> 588 Test 10: BOX, test data with anisotropic pixels
191 <param name="filter_type" value="gaussian"/> 589 ===============================================
192 </conditional> 590 -->
193 <expand macro="tests/intensity_image_diff" name="output" value="input2_gaussian.tiff" ftype="tiff"> 591 <conditional name="setup">
194 <!-- See note for Gaussian filter above. --> 592 <param name="target" value="2d"/>
195 <has_image_mean_intensity mean_intensity="0.25" eps="0.01"/> 593 <param name="input" value="input/input3_uint16.tiff"/>
594 <conditional name="filter">
595 <param name="filter_type" value="uniform"/>
596 </conditional>
597 </conditional>
598 <expand macro="tests/intensity_image_diff" name="output" value="output/input3_uniform.tiff" ftype="tiff"/>
599 <assert_stdout>
600 <has_line line="Input image shape: (1, 1, 1, 58, 64, 3)"/>
601 <has_line line="Input image axes: QTZYXC"/>
602 <has_line line="Input image dtype: uint16"/>
603 <has_line_matching expression="^Anisotropy of YX pixels/voxels: \(1\.414[0-9]+, 0\.707[0-9]+\)$"/>
604 <has_line line="Applying filter: uniform_filter with size=(2, 4), axes='YX'"/>
605 <has_line line="Output image shape: (58, 64, 3)"/>
606 <has_line line="Output image axes: YXC"/>
607 <has_line line="Output image dtype: uint16"/>
608 </assert_stdout>
609 </test>
610 <test>
611 <!--
612 Test 11: BOX, test data with anisotropic pixels and `"anisotropic": false`
613 ==========================================================================
614 -->
615 <conditional name="setup">
616 <param name="target" value="2d"/>
617 <param name="input" value="input/input3_uint16.tiff"/>
618 <conditional name="filter">
619 <param name="filter_type" value="uniform"/>
620 <param name="anisotropic" value="false"/>
621 </conditional>
622 </conditional>
623 <expand macro="tests/intensity_image_diff" name="output" value="output/input3_uniform_anisotropic-off.tiff" ftype="tiff"/>
624 <assert_stdout>
625 <has_line line="Input image shape: (1, 1, 1, 58, 64, 3)"/>
626 <has_line line="Input image axes: QTZYXC"/>
627 <has_line line="Input image dtype: uint16"/>
628 <has_line line="Applying filter: uniform_filter with size=3, axes='YX'"/>
629 <has_line line="Output image shape: (58, 64, 3)"/>
630 <has_line line="Output image axes: YXC"/>
631 <has_line line="Output image dtype: uint16"/>
632 </assert_stdout>
633 </test>
634 <test>
635 <!--
636 Test 12: MEDIAN, range of values is preserved
637 =============================================
638
639 The input file `input1_uint8.tiff` has values ranging between 23 and 254, with a mean value of 63.67.
640
641 Below, we use an assertion in addition to the `image_diff` comparison, to ensure that the range of
642 values is preserved. The motiviation behind this is that the expectation images are usually checked
643 visually, which means that the `image_diff` comparison is likely to ensure that the brightness of
644 the image is correct, thus it's good to double-check the range of values (hence the comparably large
645 value for `eps`). This also concerns the Gaussian and Box filters (see above).
646 -->
647 <conditional name="setup">
648 <param name="target" value="2d"/>
649 <param name="input" value="input/input1_uint8.tiff"/>
650 <conditional name="filter">
651 <param name="filter_type" value="median"/>
652 </conditional>
653 </conditional>
654 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_median.tiff" ftype="tiff">
655 <!-- Mean of Median filter is approximately the mean intensity value of the image: -->
656 <has_image_mean_intensity mean_intensity="63.67" eps="10"/>
196 </expand> 657 </expand>
197 </test> 658 <assert_stdout>
198 <test> 659 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
199 <param name="input" value="input2_float.tiff"/> 660 <has_line line="Input image axes: QTZYXC"/>
200 <conditional name="filter"> 661 <has_line line="Input image dtype: uint8"/>
201 <param name="filter_type" value="uniform"/> 662 <has_line line="Applying filter: median_filter with size=3, axes='YX'"/>
202 <param name="size" value="4"/> 663 <has_line line="Output image shape: (265, 329)"/>
203 </conditional> 664 <has_line line="Output image axes: YX"/>
204 <expand macro="tests/intensity_image_diff" name="output" value="input2_uniform.tiff" ftype="tiff"> 665 <has_line line="Output image dtype: uint8"/>
205 <!-- See note for Gaussian filter above. --> 666 </assert_stdout>
206 <has_image_mean_intensity mean_intensity="0.25" eps="0.01"/> 667 </test>
207 </expand> 668 <test>
208 </test> 669 <!--
209 <!-- Tests with multi-channel image (RGB) --> 670 Test 13: MEDIAN, test `size` parameter
210 <test> 671 ======================================
211 <param name="input" value="scikit-image/retina.png"/> 672 -->
212 <conditional name="filter"> 673 <conditional name="setup">
213 <param name="filter_type" value="gaussian"/> 674 <param name="target" value="2d"/>
214 <param name="sigma" value="5"/> 675 <param name="input" value="input/input1_uint8.tiff"/>
215 <conditional name="derivative"> 676 <conditional name="filter">
216 <param name="order" value="0"/> 677 <param name="filter_type" value="median"/>
217 </conditional> 678 <param name="size" value="5"/>
218 </conditional> 679 </conditional>
219 <expand macro="tests/intensity_image_diff" name="output" value="retina_gaussian_order0.tiff" ftype="tiff"/> 680 </conditional>
220 </test> 681 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_median_size5.tiff" ftype="tiff"/>
221 <test> 682 <assert_stdout>
222 <param name="input" value="scikit-image/retina.png"/> 683 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
223 <conditional name="filter"> 684 <has_line line="Input image axes: QTZYXC"/>
224 <param name="filter_type" value="gaussian"/> 685 <has_line line="Input image dtype: uint8"/>
225 <param name="sigma" value="3"/> 686 <has_line line="Applying filter: median_filter with size=5, axes='YX'"/>
226 <conditional name="derivative"> 687 <has_line line="Output image shape: (265, 329)"/>
227 <param name="order" value="2"/> 688 <has_line line="Output image axes: YX"/>
228 <param name="axis" value="0"/> 689 <has_line line="Output image dtype: uint8"/>
229 </conditional> 690 </assert_stdout>
230 </conditional> 691 </test>
231 <expand macro="tests/intensity_image_diff" name="output" value="retina_gaussian_order2_axis0.tiff" ftype="tiff"/> 692 <test>
232 </test> 693 <!--
694 Test 14: MEDIAN, test data with anisotropic pixels
695 ==================================================
696 -->
697 <conditional name="setup">
698 <param name="target" value="2d"/>
699 <param name="input" value="input/input3_uint16.tiff"/>
700 <conditional name="filter">
701 <param name="filter_type" value="median"/>
702 </conditional>
703 </conditional>
704 <expand macro="tests/intensity_image_diff" name="output" value="output/input3_median.tiff" ftype="tiff"/>
705 <assert_stdout>
706 <has_line line="Input image shape: (1, 1, 1, 58, 64, 3)"/>
707 <has_line line="Input image axes: QTZYXC"/>
708 <has_line line="Input image dtype: uint16"/>
709 <has_line_matching expression="^Anisotropy of YX pixels/voxels: \(1\.414[0-9]+, 0\.707[0-9]+\)$"/>
710 <has_line line="Applying filter: median_filter with size=(2, 4), axes='YX'"/>
711 <has_line line="Output image shape: (58, 64, 3)"/>
712 <has_line line="Output image axes: YXC"/>
713 <has_line line="Output image dtype: uint16"/>
714 </assert_stdout>
715 </test>
716 <test>
717 <!--
718 Test 15: MEDIAN, test data with anisotropic pixels and `"anisotropic": false`
719 =============================================================================
720 -->
721 <conditional name="setup">
722 <param name="target" value="2d"/>
723 <param name="input" value="input/input3_uint16.tiff"/>
724 <conditional name="filter">
725 <param name="filter_type" value="median"/>
726 <param name="anisotropic" value="false"/>
727 </conditional>
728 </conditional>
729 <expand macro="tests/intensity_image_diff" name="output" value="output/input3_median_anisotropic-off.tiff" ftype="tiff"/>
730 <assert_stdout>
731 <has_line line="Input image shape: (1, 1, 1, 58, 64, 3)"/>
732 <has_line line="Input image axes: QTZYXC"/>
733 <has_line line="Input image dtype: uint16"/>
734 <has_line line="Applying filter: median_filter with size=3, axes='YX'"/>
735 <has_line line="Output image shape: (58, 64, 3)"/>
736 <has_line line="Output image axes: YXC"/>
737 <has_line line="Output image dtype: uint16"/>
738 </assert_stdout>
739 </test>
740 <test>
741 <!--
742 Test 16: PREWITT (default is horizontal)
743 ========================================
744 -->
745 <conditional name="setup">
746 <param name="target" value="2d"/>
747 <param name="input" value="input/input1_uint8.tiff"/>
748 <conditional name="filter">
749 <param name="filter_type" value="prewitt"/>
750 </conditional>
751 </conditional>
752 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_prewitt.tiff" ftype="tiff"/>
753 <assert_stdout>
754 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
755 <has_line line="Input image axes: QTZYXC"/>
756 <has_line line="Input image dtype: uint8"/>
757 <has_line line="Applying filter: prewitt with axis=1, axes='YX'"/>
758 <has_line line="Output image shape: (265, 329)"/>
759 <has_line line="Output image axes: YX"/>
760 <has_line line="Output image dtype: float64"/>
761 </assert_stdout>
762 </test>
763 <test>
764 <!--
765 Test 17: PREWITT, test `"direction": 0` (vertical)
766 ==================================================
767 -->
768 <conditional name="setup">
769 <param name="target" value="2d"/>
770 <param name="input" value="input/input1_uint8.tiff"/>
771 <conditional name="filter">
772 <param name="filter_type" value="prewitt"/>
773 <param name="direction" value="0"/>
774 </conditional>
775 </conditional>
776 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_prewitt_direction0.tiff" ftype="tiff"/>
777 <assert_stdout>
778 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
779 <has_line line="Input image axes: QTZYXC"/>
780 <has_line line="Input image dtype: uint8"/>
781 <has_line line="Applying filter: prewitt with axis=0, axes='YX'"/>
782 <has_line line="Output image shape: (265, 329)"/>
783 <has_line line="Output image axes: YX"/>
784 <has_line line="Output image dtype: float64"/>
785 </assert_stdout>
786 </test>
787 <test>
788 <!--
789 Test 18: SOBEL (default is horizontal)
790 ======================================
791 -->
792 <conditional name="setup">
793 <param name="target" value="2d"/>
794 <param name="input" value="input/input1_uint8.tiff"/>
795 <conditional name="filter">
796 <param name="filter_type" value="sobel"/>
797 </conditional>
798 </conditional>
799 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_sobel.tiff" ftype="tiff"/>
800 <assert_stdout>
801 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
802 <has_line line="Input image axes: QTZYXC"/>
803 <has_line line="Input image dtype: uint8"/>
804 <has_line line="Applying filter: sobel with axis=1, axes='YX'"/>
805 <has_line line="Output image shape: (265, 329)"/>
806 <has_line line="Output image axes: YX"/>
807 <has_line line="Output image dtype: float64"/>
808 </assert_stdout>
809 </test>
810 <test>
811 <!--
812 Test 19: SOBEL, test `"direction": 0` (vertical)
813 ================================================
814 -->
815 <conditional name="setup">
816 <param name="target" value="2d"/>
817 <param name="input" value="input/input1_uint8.tiff"/>
818 <conditional name="filter">
819 <param name="filter_type" value="sobel"/>
820 <param name="direction" value="0"/>
821 </conditional>
822 </conditional>
823 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_sobel_direction0.tiff" ftype="tiff"/>
824 <assert_stdout>
825 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
826 <has_line line="Input image axes: QTZYXC"/>
827 <has_line line="Input image dtype: uint8"/>
828 <has_line line="Applying filter: sobel with axis=0, axes='YX'"/>
829 <has_line line="Output image shape: (265, 329)"/>
830 <has_line line="Output image axes: YX"/>
831 <has_line line="Output image dtype: float64"/>
832 </assert_stdout>
833 </test>
834 <!--
835 =========================================================================================================
836 === TESTS: 3-D images
837 =========================================================================================================
838 -->
839 <test>
840 <!--
841 Test 20: GAUSSIAN, defaults
842 ===========================
843 -->
844 <conditional name="setup">
845 <param name="target" value="3d"/>
846 <param name="input" value="input/input4_float16.tiff"/>
847 <conditional name="filter">
848 <param name="filter_type" value="gaussian"/>
849 </conditional>
850 </conditional>
851 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_gaussian.tiff" ftype="tiff"/>
852 <assert_stdout>
853 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
854 <has_line line="Input image axes: QTZYXC"/>
855 <has_line line="Input image dtype: float16"/>
856 <has_line line="Anisotropy of ZYX pixels/voxels: (2.0, 1.0, 0.5)"/>
857 <has_line line="Applying filter: gaussian_filter with sigma=(1.5, 3.0, 6.0), order=0, axes='ZYX'"/>
858 <has_line line="Output image shape: (10, 15, 18)"/>
859 <has_line line="Output image axes: ZYX"/>
860 <has_line line="Output image dtype: float16"/>
861 </assert_stdout>
862 </test>
863 <test>
864 <!--
865 Test 21: GAUSSIAN, test `"anisotropic": false`
866 ==============================================
867 -->
868 <conditional name="setup">
869 <param name="target" value="3d"/>
870 <param name="input" value="input/input4_float16.tiff"/>
871 <conditional name="filter">
872 <param name="filter_type" value="gaussian"/>
873 <param name="anisotropic" value="false"/>
874 </conditional>
875 </conditional>
876 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_gaussian_anisotropic-off.tiff" ftype="tiff"/>
877 <assert_stdout>
878 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
879 <has_line line="Input image axes: QTZYXC"/>
880 <has_line line="Input image dtype: float16"/>
881 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=0, axes='ZYX'"/>
882 <has_line line="Output image shape: (10, 15, 18)"/>
883 <has_line line="Output image axes: ZYX"/>
884 <has_line line="Output image dtype: float16"/>
885 </assert_stdout>
886 </test>
887 <test>
888 <!--
889 Test 22: GAUSSIAN, test `"axes": "YX"`
890 ======================================
891 -->
892 <conditional name="setup">
893 <param name="target" value="3d"/>
894 <param name="input" value="input/input4_float16.tiff"/>
895 <conditional name="filter">
896 <param name="filter_type" value="gaussian"/>
897 <conditional name="derivative">
898 <param name="axes" value="YX"/>
899 </conditional>
900 </conditional>
901 </conditional>
902 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_gaussian_yx.tiff" ftype="tiff"/>
903 <assert_stdout>
904 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
905 <has_line line="Input image axes: QTZYXC"/>
906 <has_line line="Input image dtype: float16"/>
907 <has_line_matching expression="^Anisotropy of YX pixels/voxels: \(1\.414[0-9]+, 0\.707[0-9]+\)$"/>
908 <has_line_matching expression="^Applying filter: gaussian_filter with sigma=\(2\.121[0-9]+, 4\.242[0-9]+\), order=0, axes='YX'$"/>
909 <has_line line="Output image shape: (10, 15, 18)"/>
910 <has_line line="Output image axes: ZYX"/>
911 <has_line line="Output image dtype: float16"/>
912 </assert_stdout>
913 </test>
914 <test>
915 <!--
916 Test 23: GAUSSIAN, test `"axes": "YZ"`
917 ======================================
918 -->
919 <conditional name="setup">
920 <param name="target" value="3d"/>
921 <param name="input" value="input/input4_float16.tiff"/>
922 <conditional name="filter">
923 <param name="filter_type" value="gaussian"/>
924 <conditional name="derivative">
925 <param name="axes" value="YZ"/>
926 </conditional>
927 </conditional>
928 </conditional>
929 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_gaussian_yz.tiff" ftype="tiff"/>
930 <assert_stdout>
931 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
932 <has_line line="Input image axes: QTZYXC"/>
933 <has_line line="Input image dtype: float16"/>
934 <has_line_matching expression="^Anisotropy of YZ pixels/voxels: \(0\.707[0-9]+, 1\.414[0-9]+\)$"/>
935 <has_line_matching expression="^Applying filter: gaussian_filter with sigma=\(4\.242[0-9]+, 2\.121[0-9]+\), order=0, axes='YZ'$"/>
936 <has_line line="Output image shape: (10, 15, 18)"/>
937 <has_line line="Output image axes: ZYX"/>
938 <has_line line="Output image dtype: float16"/>
939 </assert_stdout>
940 </test>
941 <test>
942 <!--
943 Test 24: GAUSSIAN, test `"order": 1` (default is horizontal)
944 ============================================================
945 -->
946 <conditional name="setup">
947 <param name="target" value="3d"/>
948 <param name="input" value="input/input4_float16.tiff"/>
949 <conditional name="filter">
950 <param name="filter_type" value="gaussian"/>
951 <conditional name="derivative">
952 <param name="order" value="1"/>
953 </conditional>
954 </conditional>
955 </conditional>
956 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_gaussian_order1.tiff" ftype="tiff"/>
957 <assert_stdout>
958 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
959 <has_line line="Input image axes: QTZYXC"/>
960 <has_line line="Input image dtype: float16"/>
961 <has_line line="Anisotropy of ZYX pixels/voxels: (2.0, 1.0, 0.5)"/>
962 <has_line line="Applying filter: gaussian_filter with sigma=(1.5, 3.0, 6.0), order=(0, 0, 1), axes='ZYX'"/>
963 <has_line line="Output image shape: (10, 15, 18)"/>
964 <has_line line="Output image axes: ZYX"/>
965 <has_line line="Output image dtype: float16"/>
966 </assert_stdout>
967 </test>
968 <test>
969 <!--
970 Test 25: GAUSSIAN, test `"order": 1`, `"direction": 1` (vertical)
971 =================================================================
972 -->
973 <conditional name="setup">
974 <param name="target" value="3d"/>
975 <param name="input" value="input/input4_float16.tiff"/>
976 <conditional name="filter">
977 <param name="filter_type" value="gaussian"/>
978 <conditional name="derivative">
979 <param name="order" value="1"/>
980 <conditional name="directed_3d">
981 <param name="direction" value="1"/>
982 </conditional>
983 </conditional>
984 </conditional>
985 </conditional>
986 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_gaussian_order1_direction1.tiff" ftype="tiff"/>
987 <assert_stdout>
988 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
989 <has_line line="Input image axes: QTZYXC"/>
990 <has_line line="Input image dtype: float16"/>
991 <has_line line="Anisotropy of ZYX pixels/voxels: (2.0, 1.0, 0.5)"/>
992 <has_line line="Applying filter: gaussian_filter with sigma=(1.5, 3.0, 6.0), order=(0, 1, 0), axes='ZYX'"/>
993 <has_line line="Output image shape: (10, 15, 18)"/>
994 <has_line line="Output image axes: ZYX"/>
995 <has_line line="Output image dtype: float16"/>
996 </assert_stdout>
997 </test>
998 <test>
999 <!--
1000 Test 26: GAUSSIAN, test `"order": 1`, `"axes": "XZ"`, `"direction": 1` (orthogonal)
1001 ===================================================================================
1002 -->
1003 <conditional name="setup">
1004 <param name="target" value="3d"/>
1005 <param name="input" value="input/input4_float16.tiff"/>
1006 <conditional name="filter">
1007 <param name="filter_type" value="gaussian"/>
1008 <conditional name="derivative">
1009 <param name="order" value="1"/>
1010 <conditional name="directed_3d">
1011 <param name="axes" value="XZ"/>
1012 <param name="direction" value="1"/>
1013 </conditional>
1014 </conditional>
1015 </conditional>
1016 </conditional>
1017 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_gaussian_order1_xz_direction1.tiff" ftype="tiff"/>
1018 <assert_stdout>
1019 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
1020 <has_line line="Input image axes: QTZYXC"/>
1021 <has_line line="Input image dtype: float16"/>
1022 <has_line line="Anisotropy of XZ pixels/voxels: (0.5, 2.0)"/>
1023 <has_line line="Applying filter: gaussian_filter with sigma=(6.0, 1.5), order=(0, 1), axes='XZ'"/>
1024 <has_line line="Output image shape: (10, 15, 18)"/>
1025 <has_line line="Output image axes: ZYX"/>
1026 <has_line line="Output image dtype: float16"/>
1027 </assert_stdout>
1028 </test>
1029 <test>
1030 <!--
1031 Test 27: BOX, defaults
1032 ======================
1033 -->
1034 <conditional name="setup">
1035 <param name="target" value="3d"/>
1036 <param name="input" value="input/input4_float16.tiff"/>
1037 <conditional name="filter">
1038 <param name="filter_type" value="uniform"/>
1039 </conditional>
1040 </conditional>
1041 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_uniform.tiff" ftype="tiff"/>
1042 <assert_stdout>
1043 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
1044 <has_line line="Input image axes: QTZYXC"/>
1045 <has_line line="Input image dtype: float16"/>
1046 <has_line line="Anisotropy of ZYX pixels/voxels: (2.0, 1.0, 0.5)"/>
1047 <has_line line="Applying filter: uniform_filter with size=(2, 3, 6), axes='ZYX'"/>
1048 <has_line line="Output image shape: (10, 15, 18)"/>
1049 <has_line line="Output image axes: ZYX"/>
1050 <has_line line="Output image dtype: float16"/>
1051 </assert_stdout>
1052 </test>
1053 <test>
1054 <!--
1055 Test 28: MEDIAN, defaults
1056 =========================
1057 -->
1058 <conditional name="setup">
1059 <param name="target" value="3d"/>
1060 <param name="input" value="input/input4_float16.tiff"/>
1061 <conditional name="filter">
1062 <param name="filter_type" value="median"/>
1063 </conditional>
1064 </conditional>
1065 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_median.tiff" ftype="tiff"/>
1066 <assert_stdout>
1067 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
1068 <has_line line="Input image axes: QTZYXC"/>
1069 <has_line line="Input image dtype: float16"/>
1070 <has_line line="Anisotropy of ZYX pixels/voxels: (2.0, 1.0, 0.5)"/>
1071 <has_line line="Applying filter: median_filter with size=(2, 3, 6), axes='ZYX'"/>
1072 <has_line line="Output image shape: (10, 15, 18)"/>
1073 <has_line line="Output image axes: ZYX"/>
1074 <has_line line="Output image dtype: float16"/>
1075 </assert_stdout>
1076 </test>
1077 <test>
1078 <!--
1079 Test 29: PREWITT, defaults
1080 =========================
1081 -->
1082 <conditional name="setup">
1083 <param name="target" value="3d"/>
1084 <param name="input" value="input/input4_float16.tiff"/>
1085 <conditional name="filter">
1086 <param name="filter_type" value="prewitt"/>
1087 </conditional>
1088 </conditional>
1089 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_prewitt.tiff" ftype="tiff"/>
1090 <assert_stdout>
1091 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
1092 <has_line line="Input image axes: QTZYXC"/>
1093 <has_line line="Input image dtype: float16"/>
1094 <has_line line="Applying filter: prewitt with axis=1, axes='YX'"/>
1095 <has_line line="Output image shape: (10, 15, 18)"/>
1096 <has_line line="Output image axes: ZYX"/>
1097 <has_line line="Output image dtype: float16"/>
1098 </assert_stdout>
1099 </test>
1100 <test>
1101 <!--
1102 Test 30: SOBEL, defaults
1103 =========================
1104 -->
1105 <conditional name="setup">
1106 <param name="target" value="3d"/>
1107 <param name="input" value="input/input4_float16.tiff"/>
1108 <conditional name="filter">
1109 <param name="filter_type" value="sobel"/>
1110 </conditional>
1111 </conditional>
1112 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_sobel.tiff" ftype="tiff"/>
1113 <assert_stdout>
1114 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
1115 <has_line line="Input image axes: QTZYXC"/>
1116 <has_line line="Input image dtype: float16"/>
1117 <has_line line="Applying filter: sobel with axis=1, axes='YX'"/>
1118 <has_line line="Output image shape: (10, 15, 18)"/>
1119 <has_line line="Output image axes: ZYX"/>
1120 <has_line line="Output image dtype: float16"/>
1121 </assert_stdout>
1122 </test>
1123 <!--
1124 =========================================================================================================
1125 === TESTS: Explicit `dtype` conversion
1126 =========================================================================================================
1127 -->
1128 <test>
1129 <!--
1130 Test 31: GAUSSIAN, uint8 input, test `"order": 1` (default is horizontal), `"dtype": "float16"`
1131 ===============================================================================================
1132 -->
1133 <conditional name="setup">
1134 <param name="target" value="2d"/>
1135 <param name="input" value="input/input1_uint8.tiff"/>
1136 <conditional name="filter">
1137 <param name="filter_type" value="gaussian"/>
1138 <conditional name="derivative">
1139 <param name="order" value="1"/>
1140 <param name="dtype" value="float16"/>
1141 </conditional>
1142 </conditional>
1143 </conditional>
1144 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_gaussian_order1_float16.tiff" ftype="tiff"/>
1145 <assert_stdout>
1146 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
1147 <has_line line="Input image axes: QTZYXC"/>
1148 <has_line line="Input image dtype: uint8"/>
1149 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=(0, 1), axes='YX'"/>
1150 <has_line line="Output image shape: (265, 329)"/>
1151 <has_line line="Output image axes: YX"/>
1152 <has_line line="Output image dtype: float16"/>
1153 </assert_stdout>
1154 </test>
1155 <test>
1156 <!--
1157 Test 32: PREWITT, uint8 input, `"dtype": "float16"`
1158 ===================================================
1159 -->
1160 <conditional name="setup">
1161 <param name="target" value="2d"/>
1162 <param name="input" value="input/input1_uint8.tiff"/>
1163 <conditional name="filter">
1164 <param name="filter_type" value="prewitt"/>
1165 <param name="dtype" value="float16"/>
1166 </conditional>
1167 </conditional>
1168 <expand macro="tests/intensity_image_diff" name="output" value="output/input1_prewitt_float16.tiff" ftype="tiff"/>
1169 <assert_stdout>
1170 <has_line line="Input image shape: (1, 1, 1, 265, 329, 1)"/>
1171 <has_line line="Input image axes: QTZYXC"/>
1172 <has_line line="Input image dtype: uint8"/>
1173 <has_line line="Applying filter: prewitt with axis=1, axes='YX'"/>
1174 <has_line line="Output image shape: (265, 329)"/>
1175 <has_line line="Output image axes: YX"/>
1176 <has_line line="Output image dtype: float16"/>
1177 </assert_stdout>
1178 </test>
1179 <test>
1180 <!--
1181 Test 33: SOBEL, float16 input, `"dtype": "float32"`
1182 ===================================================
1183 -->
1184 <conditional name="setup">
1185 <param name="target" value="3d"/>
1186 <param name="input" value="input/input4_float16.tiff"/>
1187 <conditional name="filter">
1188 <param name="filter_type" value="sobel"/>
1189 <param name="dtype" value="float32"/>
1190 </conditional>
1191 </conditional>
1192 <expand macro="tests/intensity_image_diff" name="output" value="output/input4_sobel_float32.tiff" ftype="tiff"/>
1193 <assert_stdout>
1194 <has_line line="Input image shape: (1, 1, 10, 15, 18, 1)"/>
1195 <has_line line="Input image axes: QTZYXC"/>
1196 <has_line line="Input image dtype: float16"/>
1197 <has_line line="Applying filter: sobel with axis=1, axes='YX'"/>
1198 <has_line line="Output image shape: (10, 15, 18)"/>
1199 <has_line line="Output image axes: ZYX"/>
1200 <has_line line="Output image dtype: float32"/>
1201 </assert_stdout>
1202 </test>
1203 <!--
1204 =========================================================================================================
1205 === TESTS: Exotic datatypes
1206 =========================================================================================================
1207 -->
1208 <test>
1209 <!--
1210 Test 34: JPG
1211 ============
1212 -->
1213 <conditional name="setup">
1214 <param name="target" value="2d"/>
1215 <param name="input" value="input/input5.jpg"/>
1216 <conditional name="filter">
1217 <param name="filter_type" value="gaussian"/>
1218 </conditional>
1219 </conditional>
1220 <expand macro="tests/intensity_image_diff" name="output" value="output/input5_gaussian.tiff" ftype="tiff"/>
1221 <assert_stdout>
1222 <has_line line="Input image shape: (1, 1, 1, 10, 10, 3)"/>
1223 <has_line line="Input image axes: QTZYXC"/>
1224 <has_line line="Input image dtype: uint8"/>
1225 <has_line line="Applying filter: gaussian_filter with sigma=3.0, order=0, axes='YX'"/>
1226 <has_line line="Output image shape: (10, 10, 3)"/>
1227 <has_line line="Output image axes: YXC"/>
1228 <has_line line="Output image dtype: uint8"/>
1229 </assert_stdout>
1230 </test>
1231 <test>
1232 <!--
1233 Test 35: 2-D OME-Zarr
1234 =====================
1235 -->
1236 <conditional name="setup">
1237 <param name="target" value="2d"/>
1238 <param name="input" value="input/input6_yx.zarr"/>
1239 <conditional name="filter">
1240 <param name="filter_type" value="gaussian"/>
1241 </conditional>
1242 </conditional>
1243 <expand macro="tests/intensity_image_diff" name="output" value="output/input6_gaussian.tiff" ftype="tiff"/>
1244 <assert_stdout>
1245 <has_line line="Input image shape: (1, 1, 1, 200, 200, 1)"/>
1246 <has_line line="Input image axes: QTZYXC"/>
1247 <has_line line="Input image dtype: float64"/>
1248 <has_line line="Anisotropy of YX pixels/voxels: (1.0, 1.0)"/>
1249 <has_line line="Applying filter: gaussian_filter with sigma=(3.0, 3.0), order=0, axes='YX'"/>
1250 <has_line line="Output image shape: (200, 200)"/>
1251 <has_line line="Output image axes: YX"/>
1252 <has_line line="Output image dtype: float64"/>
1253 </assert_stdout>
1254 </test>
1255 <test>
1256 <!--
1257 Test 36: 3-D OME-Zarr
1258 =====================
1259 -->
1260 <conditional name="setup">
1261 <param name="target" value="3d"/>
1262 <param name="input" value="input/input7_zyx.zarr"/>
1263 <conditional name="filter">
1264 <param name="filter_type" value="gaussian"/>
1265 </conditional>
1266 </conditional>
1267 <expand macro="tests/intensity_image_diff" name="output" value="output/input7_gaussian.tiff" ftype="tiff"/>
1268 <assert_stdout>
1269 <has_line line="Input image shape: (1, 1, 2, 64, 64, 1)"/>
1270 <has_line line="Input image axes: QTZYXC"/>
1271 <has_line line="Input image dtype: float64"/>
1272 <has_line line="Anisotropy of ZYX pixels/voxels: (1.0, 1.0, 1.0)"/>
1273 <has_line line="Applying filter: gaussian_filter with sigma=(3.0, 3.0, 3.0), order=0, axes='ZYX'"/>
1274 <has_line line="Output image shape: (2, 64, 64)"/>
1275 <has_line line="Output image axes: ZYX"/>
1276 <has_line line="Output image dtype: float64"/>
1277 </assert_stdout>
1278 </test>
1279 <!--
1280 =========================================================================================================
1281 === TESTS: Illegal input images
1282 =========================================================================================================
1283 -->
1284 <test expect_failure="true">
1285 <!--
1286 Test 37: Using 3-D image (with metadata) with `"target": "2d"`
1287 ==============================================================
1288 -->
1289 <conditional name="setup">
1290 <param name="target" value="2d"/>
1291 <param name="input" value="input/input4_float16.tiff"/>
1292 </conditional>
1293 </test>
1294 <test expect_failure="true">
1295 <!--
1296 Test 38: Using 2-D image (with metadata) with `"target": "3d"`
1297 ==============================================================
1298 -->
1299 <conditional name="setup">
1300 <param name="target" value="3d"/>
1301 <param name="input" value="input/input1_uint8.tiff"/>
1302 </conditional>
1303 </test>
1304 <!-- TODO: Add test for wrong `target` with OME-Zarr -->
233 </tests> 1305 </tests>
234 <help> 1306 <help>
235 1307
236 **Applies a standard, general-purpose 2-D filter to an image.** 1308 **Applies a standard, general-purpose image filter to an image.**
237 1309
238 Support for different image types: 1310 Support for different image types:
239 1311
240 - For 3-D images, the filter is applied to all z-slices of the image. 1312 - For 3-D images, filters can either be applied jointly to the 3-D image data, or separately to all 2-D slices of the image.
241 - For multi-channel images, the filter is applied to all channels of the image. 1313 - For multi-channel images, filters are applied separately to all channels of the image.
242 - For time-series images, the filter is also applied for all time steps. 1314 - For time-series images, filter also are applied separately for all time steps.
243 1315
244 Mean filters like the Gaussian filter, the box filter, or the median filter preserve both the brightness of the image, and 1316 Mean filters like the Gaussian filter, the box filter, or the median filter preserve the brightness of the image and the range
245 the range of values. This does not hold for the derivative variants of the Gaussian filter, which may produce negative values. 1317 of values. Derivative filters like 1st and 2nd order Gaussians, Prewitt filters, and Sobel filters naturally may yield negative
1318 or fractional values, and thus generally produce floating point-encoded images. The different filters are described below.
1319
1320 **Gaussian filters** are crucial for pre-processing in many image analysis tasks like edge detection and object recognition.
1321 They are also employed for image denoising, when images are deteriorated by—or approximately by—white additive Gaussian noise.
1322 Gaussian filters are linear filters that smoothen images and blur out fine details, which is why they are also used for scale
1323 selection. These filters use a Gaussian bell-shaped kernel for weighted averaging of pixels, giving more importance to central
1324 pixels and less to distant ones.
1325
1326 **Gaussian derivative operators** (1st and 2nd order Gaussians) are filters that are used in image analysis for approximate
1327 computation of the 1st and 2nd order derivatives of the image intensities. Due to their scale-space theoretical and
1328 noise-reducing properties, they are popular candidates for edge and feature detection. They are implemented by convolving an
1329 image with the derivative of a Gaussian function.
1330
1331 **Box filters** are another family of linear smoothing filter, that uses a uniform kernel for arithmetic averaging of pixels.
1332 The name stems from the rectangular shape of the kernel. The box filter corresponds to a sinc function in the frequency
1333 domain. This causes smoothing artifacts in the spatial domain. It is rarely used as a low-pass filter and is more of academic
1334 interest.
1335
1336 **Median filters** are non-linear filters, specifically well suited for reduction of impulse noise (e.g., salt-&amp;-pepper
1337 noise). Median filters compute the local median intensity value. An important advantage of median filters is that they
1338 preserve the set of intensity values in the image (or yield a subset). This trait makes them specifically well suited for
1339 smoothing of label maps and binary images. The median filters implemented in this tool uses rectangular neighborhoods for the
1340 computation of the local median values.
1341
1342 **Prewitt and Sobel filters** are popular 2-D filters for approximate computation of the 1-st order derivatives of the image
1343 intensities. Sobel filters have better isotropy properties than Prewitt filters.
246 1344
247 </help> 1345 </help>
248 <citations> 1346 <citations>
249 <citation type="doi">10.1016/j.jbiotec.2017.07.019</citation> 1347 <citation type="doi">10.1016/j.jbiotec.2017.07.019</citation>
1348 <citation type="doi">10.1038/s41592-019-0686-2</citation>
250 </citations> 1349 </citations>
251 </tool> 1350 </tool>