{
"title": "imfilter",
"category": "image/filters",
"keywords": [
"imfilter",
"filter",
"image",
"convolution",
"correlation",
"padding"
],
"summary": "Filter images or N-D arrays with correlation/convolution kernels and configurable padding.",
"references": [],
"gpu_support": {
"elementwise": false,
"reduction": false,
"precisions": [
"f32",
"f64"
],
"broadcasting": "none",
"notes": "Executes on the active acceleration provider when the 'imfilter' hook is implemented; otherwise RunMat gathers to the host automatically."
},
"fusion": {
"elementwise": false,
"reduction": false,
"max_inputs": 2,
"constants": "inline"
},
"requires_feature": null,
"tested": {
"unit": "builtins::image::filters::imfilter::tests",
"integration": "builtins::image::filters::imfilter::tests::gpu_fallback_uses_provider_upload"
},
"description": "`imfilter` applies N-D linear filters (correlation or convolution) to numeric or logical arrays. It provides MATLAB-compatible padding modes (`'replicate'`, `'symmetric'`, `'circular'`, `'fill'`), supports `'same'`, `'full'`, and `'valid'` output sizing, and can operate on GPU-resident tensors when RunMat Accelerate exposes the dedicated provider hook.",
"behaviors": [
"By default it performs correlation (`'corr'`) and returns an array the same size as the input (`'same'`) using zero padding.",
"Passing `'fill'` without an explicit value (or supplying a numeric scalar on its own) is equivalent to zero padding; the numeric argument can appear before or after the `'fill'` flag.",
"Convolution mode is available via the `'conv'` flag and matches `convn` semantics.",
"Padding modes control how out-of-bound indices are resolved: zero-fill (default `'fill'`/`'fill', 0` or a numeric pad value), `'replicate'`, `'symmetric'`, or `'circular'`.",
"Output sizing options determine whether RunMat crops (`'same'`), keeps the full convolution result (`'full'`), or returns only pixels covered completely by the kernel (`'valid'`).",
"Kernels may be generated by `fspecial` or authored manually; no automatic normalisation is applied.",
"Logical inputs are promoted to double precision (0.0/1.0) and all results are returned as double-precision tensors for MATLAB compatibility.",
"Multi-channel and higher-dimensional arrays are supported provided the filter dimensions are 1 along trailing axes that do not exist in the image."
],
"examples": [
{
"description": "Smoothing an image with a 3x3 average filter",
"input": "I = [1 2; 3 4];\nH = ones(3) / 9;\nJ = imfilter(I, H); % default zero padding, correlation",
"output": "J =\n 1.1111 1.1111\n 1.1111 1.1111"
},
{
"description": "Preserving borders with replicate padding",
"input": "I = magic(3);\nH = ones(3);\nJ = imfilter(I, H, 'replicate')",
"output": "J =\n 45 45 45\n 45 45 45\n 45 45 45"
},
{
"description": "Computing the full convolution result",
"input": "I = [1 2; 3 4];\nH = [1 2; 3 4];\nJ = imfilter(I, H, 'full')",
"output": "J =\n 0 0 0\n 0 4 11\n 0 14 30"
},
{
"description": "Switching to convolution mode",
"input": "I = reshape(1:6, [3 2]);\nH = [1 2; 3 4];\nJ = imfilter(I, H, 'conv'); % equivalent to convn(I, rot90(H,2), 'same')",
"output": "J =\n 1 6\n 5 25\n 9 35"
},
{
"description": "Wrapping edges with circular padding",
"input": "I = [1 2; 3 4];\nH = [0 1; 1 0];\nJ = imfilter(I, H, 'circular')",
"output": "J =\n 5 5\n 5 5"
}
],
"faqs": [
{
"question": "Which modes does `imfilter` support?",
"answer": "The builtin accepts `'corr'` (default) or `'conv'` to switch between correlation and convolution. Convolution is equivalent to correlating with the kernel rotated 180° in each dimension."
},
{
"question": "How do `'same'`, `'full'`, and `'valid'` differ?",
"answer": "`'same'` crops the result to the input size, `'full'` preserves every contribution from the convolution, and `'valid'` keeps only elements where the kernel lies fully within the original array (possibly returning empty slices)."
},
{
"question": "How does zero padding differ from `'fill'`?",
"answer": "Passing a numeric scalar (or the `'fill', padval` sequence) pads the image with that constant value. The default behaviour is equivalent to `'fill', 0`."
},
{
"question": "Can I filter RGB or higher-dimensional arrays?",
"answer": "Yes. The kernel must either match each image dimension or use size 1 along trailing axes (e.g., a 3×3×1 filter applied independently to each colour channel)."
},
{
"question": "Does `imfilter` normalise the kernel automatically?",
"answer": "No. The kernel is used exactly as supplied. Utilities such as `fspecial('average', ...)` or manual scaling should be used when normalisation is desired."
},
{
"question": "What happens when the kernel is larger than the image?",
"answer": "For `'same'` and `'full'`, the builtin applies the filter with the chosen padding, producing sensible output. `'valid'` returns an empty array for dimensions where the kernel exceeds the image size."
},
{
"question": "How does `imfilter` interact with the fusion planner?",
"answer": "The builtin registers a custom GPU spec rather than a fusion template. The planner treats it as a standalone op, enabling provider specialisation without attempting to fold it into generic fusion chains."
},
{
"question": "Is logical input supported?",
"answer": "Yes. Logical arrays are promoted to double precision (0.0/1.0) during filtering, mirroring MATLAB behaviour."
}
],
"links": [
{
"label": "fspecial",
"url": "./fspecial"
},
{
"label": "gpuArray",
"url": "./gpuarray"
},
{
"label": "gather",
"url": "./gather"
},
{
"label": "filter2",
"url": "./filter2"
}
],
"source": {
"label": "crates/runmat-runtime/src/builtins/image/filters/imfilter.rs",
"url": "crates/runmat-runtime/src/builtins/image/filters/imfilter.rs"
},
"gpu_residency": "RunMat automatically keeps tensors on the GPU when the acceleration provider implements the `imfilter` hook, so explicit `gpuArray` calls are rarely necessary. For backwards compatibility and manual residency control, you may still wrap inputs in `gpuArray`; the builtin forwards handles directly to the provider. When the hook is absent, RunMat gathers arrays to the host transparently, ensuring functional parity with MATLAB even without a GPU implementation.",
"gpu_behavior": [
"When the active acceleration provider implements the custom `imfilter` hook, the builtin keeps the image and kernel on the device, honouring padding and size options without host round-trips. Mixed-residency inputs are handled automatically: device images cause host kernels to be uploaded on demand, and failures to upload or execute simply fall back to the reference path. Providers that do not yet expose this hook trigger a transparent fallback—RunMat gathers the operands to the host, executes the scalar reference implementation, and (when appropriate) returns a host tensor. This guarantees correctness while still allowing future GPU acceleration with no API surface changes."
]
}