# HG changeset patch
# User imgteam
# Date 1765578106 0
# Node ID 0cb07fefbe70492bf6a822f5703783010811f2bb
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/ridge_filter/ commit 85b0f6afacb8933db19e03682559cc4d71031cf1
diff -r 000000000000 -r 0cb07fefbe70 creators.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/creators.xml Fri Dec 12 22:21:46 2025 +0000
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 0cb07fefbe70 filter_skimage.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/filter_skimage.py Fri Dec 12 22:21:46 2025 +0000
@@ -0,0 +1,111 @@
+import argparse
+import json
+from typing import (
+ Any,
+ Callable,
+)
+
+import giatools
+import numpy as np
+import skimage.filters
+
+
+filters = {
+ 'frangi': lambda img, **kwargs: (
+ apply_nd_filter(skimage.filters.frangi, img, **kwargs)
+ ),
+ 'hessian': lambda img, **kwargs: (
+ apply_nd_filter(skimage.filters.hessian, img, **kwargs)
+ ),
+ 'laplace': lambda img, **kwargs: (
+ apply_nd_filter(skimage.filters.laplace, img, **kwargs)
+ ),
+ 'meijering': lambda img, **kwargs: (
+ apply_nd_filter(skimage.filters.meijering, img, **kwargs)
+ ),
+ 'sato': lambda img, **kwargs: (
+ apply_nd_filter(skimage.filters.sato, img, **kwargs)
+ ),
+}
+
+
+def apply_nd_filter(
+ filter_impl: Callable[[np.ndarray, Any, ...], np.ndarray],
+ img: giatools.Image,
+ dtype: str,
+ **kwargs: Any,
+) -> giatools.Image:
+ """
+ Apply the filter to the 2-D/3-D, potentially multi-frame and multi-channel image.
+ """
+ result_data = np.empty(img.data.shape, dtype=dtype)
+ for qtc in np.ndindex(
+ img.data.shape[ 0], # Q axis
+ img.data.shape[ 1], # T axis
+ img.data.shape[-1], # C axis
+ ):
+ sl = np.s_[*qtc[:2], ..., qtc[2]] # noqa: E999
+ arr = img.data[sl]
+ assert arr.ndim == 3 # sanity check, should always be True
+
+ # Perform 2-D or 3-D filtering
+ if arr.shape[0] == 1:
+ info = 'Performing 2-D filtering'
+ result_data[sl][0] = filter_impl(arr[0], **kwargs).astype(dtype)
+ else:
+ info = 'Performing 3-D filtering'
+ result_data[sl] = filter_impl(arr, **kwargs).astype(dtype)
+
+ # Print status info
+ print(info)
+
+ # Return results as 16bit, 32bit, or 64bit floating point
+ return giatools.Image(result_data.astype(dtype), img.axes)
+
+
+def apply_filter(
+ input_filepath: str,
+ output_filepath: str,
+ filter_type: str,
+ **kwargs: Any,
+):
+ # Validate and transform input parameters
+ params = dict(kwargs)
+ if (sigma_min := params.pop('sigma_min', None)) is not None and (sigma_max := params.pop('sigma_max', None)) is not None:
+ num_sigma = params.pop('num_sigma')
+ if sigma_min < sigma_max:
+ params['sigmas'] = np.linspace(sigma_min, sigma_max, num_sigma)
+ elif sigma_min == sigma_max:
+ params['sigmas'] = [sigma_min]
+ else:
+ raise ValueError(f'Minimum sigma ({sigma_min:g}) must not be greater than Maximum sigma ({sigma_max:g})')
+
+ # Read the input image
+ img = giatools.Image.read(input_filepath)
+
+ # Perform filtering
+ print(f'Applying filter: "{filter_type}"')
+ filter_impl = filters[filter_type]
+ res = filter_impl(img, **params).normalize_axes_like(img.original_axes)
+
+ # Adopt metadata and write the result
+ res.metadata = img.metadata
+ res.write(output_filepath, backend='tifffile')
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument('input', type=str)
+ parser.add_argument('output', type=str)
+ parser.add_argument('params', type=str)
+ args = parser.parse_args()
+
+ # Read the config file
+ with open(args.params) as cfgf:
+ cfg = json.load(cfgf)
+
+ apply_filter(
+ args.input,
+ args.output,
+ **cfg,
+ )
diff -r 000000000000 -r 0cb07fefbe70 skimage.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/skimage.xml Fri Dec 12 22:21:46 2025 +0000
@@ -0,0 +1,270 @@
+
+ with scikit-image
+
+ creators.xml
+ tests.xml
+ 0.22.0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ operation_3443
+
+
+ galaxy_image_analysis
+ scikit-image
+ scikit-image
+
+
+ scikit-image
+ giatools
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+**Applies a ridge filter to an image.**
+
+Ridge filters can be used to detect ridge-like structures, such as neurites, tubes, vessels, wrinkles, or rivers. Different
+ridge filters may be suited for detecting different structures, e.g., depending on contrast or noise level. 2-D and 3-D
+images are supported. For multi-channel images, the filter is applied to all channels of the image. For time-series images,
+the filter is also applied for all time steps.
+
+Frangi vesselness filter
+========================
+
+Filter an image with the Frangi vesselness filter. This filter can be used to detect continuous ridges, e.g. vessels,
+wrinkles, rivers. It can be used to calculate the fraction of the whole image containing such objects. Calculates the
+eigenvalues of the Hessian to compute the similarity of an image region to vessels, according to the method described in
+Frangi et al. (1998).
+
+Hybrid Hessian filter
+=====================
+
+Filter an image with the Hybrid Hessian filter (Schrijver 2001, Kroon 2009). This filter can be used to detect continuous
+edges, e.g. vessels, wrinkles, rivers. It can be used to calculate the fraction of the whole image containing such objects.
+Almost equal to Frangi filter, but uses alternative method of smoothing.
+
+Laplace filter
+==============
+
+Find the edges of an image using the Laplace operator.
+
+Meijering neuriteness filter
+============================
+
+Filter an image with the Meijering neuriteness filter. This filter can be used to detect continuous ridges, e.g. neurites,
+wrinkles, rivers. It can be used to calculate the fraction of the whole image containing such objects. Calculates the
+eigenvalues of the Hessian to compute the similarity of an image region to neurites, according to the method described in
+Meijering et al. (2004).
+
+Sato tubeness filter
+====================
+
+Filter an image with the Sato tubeness filter. This filter can be used to detect continuous ridges, e.g. tubes, wrinkles,
+rivers. It can be used to calculate the fraction of the whole image containing such objects. Calculates the eigenvalues of
+the Hessian to compute the similarity of an image region to tubes, according to the method described in Sato et al. (1998).
+
+
+
+ 10.1007/BFb0056195
+ 10.1002/cyto.a.20022
+ 10.1016/S1361-8415(98)80009-1
+
+
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_0z_0t_0q.tiff
Binary file test-data/retina_0c_0z_0t_0q.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_0z_0t_0q_hessian.tiff
Binary file test-data/retina_0c_0z_0t_0q_hessian.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_0z_0t_2q.tiff
Binary file test-data/retina_0c_0z_0t_2q.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_0z_0t_2q_sato.tiff
Binary file test-data/retina_0c_0z_0t_2q_sato.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_0z_3t_0q.tiff
Binary file test-data/retina_0c_0z_3t_0q.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_0z_3t_0q_meijering.tiff
Binary file test-data/retina_0c_0z_3t_0q_meijering.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_5z_0t_0q.tiff
Binary file test-data/retina_0c_5z_0t_0q.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_0c_5z_0t_0q_laplace.tiff
Binary file test-data/retina_0c_5z_0t_0q_laplace.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_frangi.tiff
Binary file test-data/retina_frangi.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_inv_0c_0z_0t_0q.tiff
Binary file test-data/retina_inv_0c_0z_0t_0q.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/retina_inv_0c_0z_0t_0q_frangi.tiff
Binary file test-data/retina_inv_0c_0z_0t_0q_frangi.tiff has changed
diff -r 000000000000 -r 0cb07fefbe70 test-data/scikit-image/LICENSE.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/scikit-image/LICENSE.txt Fri Dec 12 22:21:46 2025 +0000
@@ -0,0 +1,28 @@
+Files: *
+Copyright: 2009-2022 the scikit-image team
+License: BSD-3-Clause
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -r 000000000000 -r 0cb07fefbe70 test-data/scikit-image/retina.png
Binary file test-data/scikit-image/retina.png has changed
diff -r 000000000000 -r 0cb07fefbe70 tests.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests.xml Fri Dec 12 22:21:46 2025 +0000
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+