@@ -977,6 +977,88 @@ Notes:
977977- Every value in the input must be present in the mapping.
978978- Non-contiguous inputs are copied before entering C++.
979979
980+ ## Image Filters
981+
982+ ` bioimage-cpp ` ships a small Gaussian-derivative filter set under
983+ ` bic.filters ` . The scope is the "ilastik filter set" exposed by
984+ ` fastfilters ` , which is also the most-used subset of ` vigra.filters ` .
985+
986+ Vigra / fastfilters:
987+
988+ ``` python
989+ import vigra.filters as vf
990+ out = vf.gaussianSmoothing(img, sigma = 1.5 )
991+ ev = vf.hessianOfGaussianEigenvalues(img, scale = 1.5 )
992+
993+ import fastfilters as ff
994+ out = ff.gaussianSmoothing(img, sigma = 1.5 )
995+ ev = ff.hessianOfGaussianEigenvalues(img, scale = 1.5 )
996+ ```
997+
998+ bioimage-cpp:
999+
1000+ ``` python
1001+ import bioimage_cpp as bic
1002+
1003+ out = bic.filters.gaussian_smoothing(img, sigma = 1.5 )
1004+ ev = bic.filters.hessian_of_gaussian_eigenvalues(img, sigma = 1.5 )
1005+ ```
1006+
1007+ Name mapping:
1008+
1009+ | vigra / fastfilters name | bioimage-cpp name |
1010+ | --- | --- |
1011+ | ` gaussianSmoothing ` | ` gaussian_smoothing ` |
1012+ | ` gaussianDerivative ` | ` gaussian_derivative ` |
1013+ | ` gaussianGradientMagnitude ` | ` gaussian_gradient_magnitude ` |
1014+ | ` laplacianOfGaussian ` | ` laplacian_of_gaussian ` |
1015+ | ` hessianOfGaussianEigenvalues ` | ` hessian_of_gaussian_eigenvalues ` |
1016+ | ` structureTensorEigenvalues ` | ` structure_tensor_eigenvalues ` |
1017+
1018+ Common parameters:
1019+
1020+ - ` sigma ` is a positive scalar or a per-axis sequence of length
1021+ ` image.ndim ` . Anisotropic sigma is supported on every filter.
1022+ - ` gaussian_derivative ` takes an ` order ` argument that is a scalar or a
1023+ per-axis sequence of ints in ` {0, 1, 2} ` .
1024+ - ` structure_tensor_eigenvalues ` takes positional ` inner_sigma ` and
1025+ ` outer_sigma ` (vigra calls them ` innerScale ` / ` outerScale ` ).
1026+ - ` window_size ` controls the kernel radius:
1027+ ` radius = ceil(window_size * sigma) ` . ` 0.0 ` (the default) selects the
1028+ vigra-style default ` 3 + 0.5 * order ` . Matches the same-named parameter
1029+ in vigra/fastfilters.
1030+
1031+ Important differences from vigra and fastfilters:
1032+
1033+ - Only 2D and 3D scalar (single-channel) inputs are supported in v1.
1034+ Channels and leading batch axes should be looped externally — matches
1035+ fastfilters' convention. Vigra's ` taggedView ` /` AxisInfo ` machinery is
1036+ not reproduced.
1037+ - C++ kernels operate on ` float32 ` . ` float64 ` inputs are accepted and the
1038+ output is cast back to ` float64 ` . ` uint8 ` and ` uint16 ` are accepted with
1039+ a ` float32 ` output (the typical ML-feature use case).
1040+ - Boundary handling is ` mirror ` (matches scipy ` mode="mirror" ` —
1041+ reflection without edge-pixel repeat). Other boundary modes are not
1042+ exposed yet; the C++ layer carries an enum for future tiled processing.
1043+ - Eigenvalue outputs have a trailing axis of size ` image.ndim ` , sorted
1044+ largest → smallest. This matches ` fastfilters ` . To get vigra's
1045+ ascending order, reverse with ` result[..., ::-1] ` .
1046+ - No IIR / recursive Gaussian, no ` convolve ` / ` recursiveFilter2D ` , no
1047+ morphology, no distance transforms, no nonlinear diffusion, and no
1048+ non-local means in v1. Use ` scipy.ndimage ` , ` skimage ` , or the original
1049+ vigra/fastfilters bindings if you need those.
1050+
1051+ Implementation notes:
1052+
1053+ - All six filters are written as portable C++20 scalar code that the
1054+ compiler auto-vectorizes. No SIMD intrinsics, no per-file ISA flags, no
1055+ runtime CPU dispatch, no vendored SIMD library. This keeps the build
1056+ light enough to ship as portable PyPI wheels across Linux/macOS/Windows
1057+ and x86_64/arm64.
1058+ - Single-threaded for now. Threading can be added later via
1059+ ` detail/threading.hxx::parallel_for_chunks ` without changing the
1060+ public API.
1061+
9801062## I/O and Build Dependencies
9811063
9821064` bioimage-cpp ` intentionally does not replace nifty or affogato I/O helpers.
0 commit comments