-
Notifications
You must be signed in to change notification settings - Fork 0
API Filter
Namespace: acl::filter (cpp) / acl::neon::filter (NEON)
Gaussian blur (low-pass filter), accelerated with a separable kernel (row kernel × column kernel).
Tier: Starter+
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
ST |
uint8_t, uint16_t, float |
— |
DT |
uint8_t, uint16_t, float |
— |
template<class ST, class DT>
int gaussianBlur(
const ST* srcImage, DT* dstImage,
int width, int height, int cn,
int srcStride, int dstStride,
int kRadiusX, int kRadiusY,
double sigmaX = 0.0, double sigmaY = 0.0,
ST* constant = nullptr,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const ST* / DT*
|
input / output; dstImage must be pre-allocated |
non-null |
width, height
|
int |
Image size (pixels) | > 0 |
cn |
int |
Channel count | 1 or 3 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
kRadiusX, kRadiusY
|
int |
Kernel radius; kernel size = 2r+1 | ≥ 1 |
sigmaX, sigmaY
|
double |
Gaussian sigma |
0 = auto (σ = 0.15·kSize + 0.35) |
constant |
ST* |
BORDER_CONSTANT fill-value pointer |
nullptr |
bt |
acl::BorderType |
Border handling | BORDER_REFLECT_101 |
The NEON layer provides fixed-kernel and generic entry points:
| Entry point | Kernel | Channels | Tier | sigma configurable |
|---|---|---|---|---|
gaussianBlur3x3 |
3×3 | 1 | Starter+ | — |
gaussianBlur3x3_3ch |
3×3 | 3 | Starter+ | — |
gaussianBlur5x5 |
5×5 | 1 | Starter+ | — |
gaussianBlur11x11 |
11×11 | 1 | Starter+ | — |
gaussianBlur (generic) |
any 2r+1 | 1 | Starter+ | ✅ |
gaussianBlur5x5_3ch |
5×5 | 3 | Starter+ | — |
Trial package note: Trial does not include gaussianBlur. Use the resize wrappers
acl::trial::resizeBilinear2xDown_cpp(const uint8_t*, uint8_t*)oracl::trial::resizeBilinear2xDown_neon(const uint8_t*, uint8_t*)for the Trial demo surface.
Fixed-kernel signature (3x3 / 5x5 / 11x11 / 3x3_3ch / 5x5_3ch share the same signature):
int gaussianBlur3x3( // or gaussianBlur5x5 / gaussianBlur11x11 / gaussianBlur3x3_3ch / gaussianBlur5x5_3ch
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
uint8_t constant = 0,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);Generic signature (supports arbitrary radius / sigma):
int gaussianBlur(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride, int dstStride,
int kRadiusX, int kRadiusY,
double sigmaX = 0.0, double sigmaY = 0.0,
int constant = 0,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);Smart dispatch: when
kSize ∈ {3, 5, 11}andsigma = 0, the generic version delivers the same throughput as the corresponding fixed-kernel variant; other(kSize, sigma)combinations fall back to the dynamicsepFilter2Dperformance profile.
#include <acl/acl.h>
#include <acl/api.h>
acl::init("license.dat");
uint8_t srcImage[1920*1080], dstImage[1920*1080];
// Case 1: 3×3 fixed kernel (Starter+ paid API)
acl::neon::filter::gaussianBlur3x3(srcImage, dstImage, 1920, 1080);
// Case 2: 5×5 + custom sigma (Starter+)
acl::neon::filter::gaussianBlur(srcImage, dstImage, 1920, 1080, 0, 0, 2, 2, 1.5, 1.5);Box (mean) filter; all pixels within the kernel are summed with equal weight. Optional normalization (when normalize=true the result is divided by the kernel size, which is the standard mean filter).
Tier: Starter+
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
ST, DT (CPP) |
{uint8_t, uint16_t, float} |
— |
DT (NEON) |
{uint8_t, int} (src is uint8_t) |
NEON-only |
template<class ST, class DT>
int boxFilter(
const ST* srcImage, DT* dstImage,
int width, int height, int cn,
int srcStride, int dstStride,
int kRadius,
bool isNormalize = true,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const ST* / DT*
|
input / output | non-null |
width, height
|
int |
Image size (pixels) | > 0 |
cn |
int |
Channel count | 1 or 3 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
kRadius |
int |
Kernel radius (kSize = 2r+1) | ≥ 1 |
isNormalize |
bool |
true → mean (divide by kSize²); false → sum |
true |
bt |
acl::BorderType |
Border handling | BORDER_REFLECT_101 |
| Entry point | Kernel | Channels | Tier |
|---|---|---|---|
boxFilter3x3 |
3×3 | 1 | Starter+ |
boxFilter5x5 |
5×5 | 1 | Starter+ |
boxFilter (generic) |
any 2r+1 | 1 | Starter+ |
There is no NEON entry point for 3 channels yet; use the CPP version
acl::filter::boxFilter<uint8_t,uint8_t>(..., cn=3).
Fixed-kernel signature (boxFilter3x3 / boxFilter5x5):
template<class DT>
int boxFilter3x3( // or boxFilter5x5
const uint8_t* srcImage, DT* dstImage,
int width, int height,
int srcStride, int dstStride,
int constant = 0,
bool isNormalize = true,
int cn = 1,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);Generic signature:
template<class DT>
int boxFilter(
const uint8_t* srcImage, DT* dstImage,
int width, int height,
int srcStride, int dstStride,
int kRadius, int constant,
bool isNormalize = true,
int cn = 1,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);DT supports uint8_t (normalize) / uint32_t (no normalize, overflow-safe). cn is a runtime parameter (1 or 3).
uint8_t srcImage[1920*1080], dstImage[1920*1080];
uint32_t dstSum[1920*1080];
// 3×3 mean filter
acl::neon::filter::boxFilter3x3<uint8_t>(srcImage, dstImage, 1920, 1080, 0, 0);
// 5×5 sum (not normalized, u32 output)
acl::neon::filter::boxFilter5x5<uint32_t>(
srcImage, dstSum, 1920, 1080, 0, 0,
/*constant=*/0, /*isNormalize=*/false, /*cn=*/1,
acl::BorderType::BORDER_REPLICATE);Generic 2D convolution (arbitrary kernel). Internally detects separable kernels; if separable, automatically converts to sepFilter2D for speedup.
Tier: Starter+
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
ST |
uint8_t, uint16_t, float |
— |
DT |
uint8_t, uint16_t, float |
— |
KT |
uint8_t, uint16_t, float |
— |
template<class ST, class DT, class KT>
int filter2D(
const ST* srcImage, DT* dstImage,
int width, int height, int cn,
int srcStride, int dstStride,
const KT* kernel, int kRadiusX, int kRadiusY,
const ST* constant = nullptr,
bool isNormalize = true,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const ST* / DT*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 or 3 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
kernel |
const KT* |
Kernel data, row-major, size (2rX+1)×(2rY+1)
|
non-null |
kRadiusX, kRadiusY
|
int |
Kernel radius | ≥ 1 |
constant |
const ST* |
BORDER_CONSTANT fill-value pointer |
nullptr |
isNormalize |
bool |
When true, output is divided by sum of kernel elements |
true |
bt |
acl::BorderType |
Border handling | BORDER_REFLECT_101 |
template<class DT, class KT>
int filter2D(
const uint8_t* srcImage, DT* dstImage,
int width, int height,
int srcStride, int dstStride,
const KT* kernel, int kRadiusX, int kRadiusY,
int constant = 0,
bool isNormalize = true,
int cn = 1,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);DT / KT: typically (uint8_t, float) or (int32_t, int32_t).
uint8_t srcImage[1920*1080], dstImage[1920*1080];
// 5×5 Laplacian kernel (not normalized, sharpen)
int K[25] = { 0, 0,-1, 0, 0,
0,-1,-2,-1, 0,
-1,-2,17,-2,-1,
0,-1,-2,-1, 0,
0, 0,-1, 0, 0 };
acl::filter::filter2D<uint8_t, uint8_t, int>(
srcImage, dstImage, 1920, 1080, 1, 0, 0, K, 2, 2,
nullptr, /*isNormalize=*/false, acl::BorderType::BORDER_REPLICATE);Separable 2D convolution: first convolves along rows with kernelX, then along columns with kernelY. Faster than filter2D: O(k) → O(2k).
Tier: Starter+
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
ST |
uint8_t, uint16_t, float |
— |
DT |
uint8_t, uint16_t, float |
— |
KT |
uint8_t, uint16_t, float |
— |
template<class ST, class DT, class KT>
int sepFilter2D(
const ST* srcImage, DT* dstImage,
int width, int height, int cn,
int srcStride, int dstStride,
const KT* kernelX, const KT* kernelY,
int kRadiusX, int kRadiusY,
const ST* constant = nullptr,
bool isNormalize = true,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const ST* / DT*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 or 3 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
kernelX, kernelY
|
const KT* |
Row / column 1D kernels, lengths 2rX+1 / 2rY+1 respectively |
non-null |
kRadiusX, kRadiusY
|
int |
Kernel radius | ≥ 1 |
constant |
const ST* |
BORDER_CONSTANT fill-value pointer |
nullptr |
isNormalize |
bool |
If true divide by kernel sum |
true |
bt |
acl::BorderType |
Border-handling mode | BORDER_REFLECT_101 |
template<class KT>
int sepFilter2D(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride, int dstStride,
const KT* kernelX, const KT* kernelY,
int kRadiusX, int kRadiusY,
int constant = 0,
int cn = 1,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);cn = 1 or 3 (channel count selected at runtime). KT: usually float.
uint8_t srcImage[1920*1080], dstImage[1920*1080];
// Decompose Gaussian 5×5 into [1,4,6,4,1]/16 × [1,4,6,4,1]/16
float kx[5] = {1,4,6,4,1}, ky[5] = {1,4,6,4,1};
acl::neon::filter::sepFilter2D<float>(
srcImage, dstImage, 1920, 1080, 0, 0, kx, ky, 2, 2, /*constant=*/0, /*cn=*/1);3×3 Sobel edge-detection operator. The runtime flag isGradX selects whether to compute Gx (horizontal gradient) or Gy (vertical gradient).
Tier: Starter+
Channels: 1ch (call separately per channel or use filter2D)
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
ST |
{uint8_t, uint16_t, float} |
— |
DT |
typically int16_t / int32_t / float
|
— |
Output type: int16_t (short) (since gradient values may be negative) |
template<class ST, class DT>
int sobel3x3(
const ST* srcImage, DT* dstImage,
int width, int height, int cn,
int srcStride = 0, int dstStride = 0,
const ST* constant = nullptr,
bool isGradX = true,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const ST* / DT*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 or 3 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
constant |
const ST* |
BORDER_CONSTANT fill value |
nullptr |
isGradX |
bool |
true: Gx (horizontal); false: Gy (vertical) |
true |
bt |
acl::BorderType |
Border-handling mode | BORDER_REFLECT_101 |
Both directions require two separate calls.
int sobel3x3(
const uint8_t* srcImage, int16_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
int constant = 0,
bool isGradX = true,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);int16_t gx[1920*1080], gy[1920*1080];
acl::neon::filter::sobel3x3(src_u8, gx, 1920, 1080, 0, 0, 0, /*isGradX=*/true); // Gx
acl::neon::filter::sobel3x3(src_u8, gy, 1920, 1080, 0, 0, 0, /*isGradX=*/false); // Gy
// Gradient magnitude can be composed via acl::arithmetic::phaseMagnitude3×3 Scharr edge-detection operator. Offers better rotational symmetry than Sobel and slightly higher numerical precision.
Tier: Starter+
Channels: 1ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
ST |
{uint8_t, uint16_t, float} |
— |
DT |
typically int16_t / int32_t / float
|
— |
Output type: int16_t
|
template<class ST, class DT>
int scharr(
const ST* srcImage, DT* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
const ST* constant = nullptr,
bool isGradX = true,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);Parameter semantics are the same as sobel3x3 (only the kernel coefficients are Scharr [-3, -10, -3; 0, 0, 0; 3, 10, 3] instead of Sobel).
int scharr(
const uint8_t* srcImage, int16_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
bool isGradX = true,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);int16_t gx[1920*1080];
acl::neon::filter::scharr(src_u8, gx, 1920, 1080, 0, 0, /*isGradX=*/true); // Gx (Scharr)Laplacian operator (second-order gradient), used for edge detection or sharpening. Internally performs two convolutions with a 3×3 or larger kernel.
Tier: Starter+
Channels: 1ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
ST |
{uint8_t, uint16_t, float} |
— |
DT |
typically int16_t / int32_t / float
|
— |
Output type: int16_t (second-order gradient may be negative) |
template<class ST, class DT>
int laplacian(
const ST* srcImage, DT* dstImage,
int width, int height, int cn,
int srcStride = 0, int dstStride = 0,
int ksize = 1, double scale = 1.0, double delta = 0.0,
const ST* constant = nullptr,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const ST* / DT*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
ksize |
int |
Kernel aperture size |
1 (= 3×3 standard Laplacian) |
scale |
double |
Output scaling factor | 1.0 |
delta |
double |
Output offset | 0.0 |
constant |
const ST* |
BORDER_CONSTANT fill value |
nullptr |
bt |
acl::BorderType |
Border-handling mode | BORDER_REFLECT_101 |
int laplacian(
const uint8_t* srcImage, int16_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
int ksize = 1, int constant = 0,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);The NEON version omits
scale/delta(fixed at 1.0 / 0.0). For scaling, use the CPP version.
uint8_t srcImage[1920*1080];
int16_t dstImage[1920*1080];
acl::neon::filter::laplacian(srcImage, dstImage, 1920, 1080);Canny edge detection. Typical pipeline: Gaussian blur → gradient → non-maximum suppression → double-threshold linking.
Tier: Starter+
Channels: 1ch (grayscale input)
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
Src_T |
uint8_t, uint16_t
|
CPP backend |
Src_T |
uint8_t |
NEON backend |
int canny(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int low_thresh, int high_thresh,
int aperture_size = 3,
int srcStride = 0, int dstStride = 0,
bool l2GradFlag = true);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage |
const uint8_t* |
Input grayscale image | non-null |
dstImage |
uint8_t* |
Output binary edge image (0 / 255) | non-null |
width, height
|
int |
Image size | > 0 |
low_thresh, high_thresh
|
int |
Low / high double thresholds | low < high |
aperture_size |
int |
Sobel kernel aperture |
3 (only 3 is supported) |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
l2GradFlag |
bool |
true: L2 Euclidean gradient; false: L1 gradient (faster) |
true |
uint8_t srcImage[1920*1080], dstImage[1920*1080];
acl::neon::filter::canny(srcImage, dstImage, 1920, 1080, 50, 150);Basic morphological operators: erosion (erode, taking the minimum over kernel coverage) and dilation (dilate, taking the maximum). Uses the O(N) van Herk / Gil-Werman algorithm; runtime is independent of kernel size.
Tier: Starter+
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T |
uint8_t, uint16_t, float |
— |
Kernel shape: square (determined by radius; actual kernel size = 2r+1) |
template<class T>
int erode(
const T* srcImage, T* dstImage,
int width, int height, int cn, int radius,
int srcStride = 0, int dstStride = 0);
template<class T>
int dilate(
const T* srcImage, T* dstImage,
int width, int height, int cn, int radius,
int srcStride = 0, int dstStride = 0);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const T* / T*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 or 3 |
radius |
int |
Structuring-element radius (square kernel, size = 2r+1) | ≥ 1 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
int erode( // or dilate
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height, int cn, int radius,
int srcStride = 0, int dstStride = 0);Parameter semantics match the CPP version.
uint8_t srcImage[1920*1080], dstImage[1920*1080];
// 3×3 erosion (radius=1)
acl::filter::erode<uint8_t>(srcImage, dstImage, 1920, 1080, 1, 1);
// 11×11 dilation (radius=5; the O(N) algorithm is unaffected by size)
acl::filter::dilate<uint8_t>(srcImage, dstImage, 1920, 1080, 1, 5);3×3 median filter — outputs the median of the 9 pixels within the kernel. Typical use: salt-and-pepper noise removal.
Tier: Starter+
Channels: 1ch / 3ch
Inplace: supported (src == dst OK)
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
DT |
uint8_t, uint16_t, float |
— |
| Kernel size: 3×3 only (5×5 and larger are not implemented) |
template<class DT>
int medianFilter3x3(
const DT* srcImage, DT* dstImage,
int width, int height,
int cn = 1,
int srcStride = 0, int dstStride = 0,
DT borderValue = 0,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const DT* / DT*
|
input / output (inplace supported) | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
borderValue |
DT |
BORDER_CONSTANT fill value |
0 |
bt |
acl::BorderType |
Border-handling mode | BORDER_REFLECT_101 |
| Entry point | Channels | Tier |
|---|---|---|
medianFilter3x3 |
1 | Starter+ |
medianFilter3x3_3ch |
3 | Starter+ |
int medianFilter3x3( // or medianFilter3x3_3ch
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
uint8_t borderValue = 0,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);uint8_t srcImage[1920*1080];
// Salt-and-pepper denoise (in-place)
acl::neon::filter::medianFilter3x3(srcImage, srcImage, 1920, 1080);Edge-preserving smoothing — bilateral filter; simultaneously considers spatial distance and pixel-value difference, denoising while preserving edges.
Tier: Pro+
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T (CPP) |
uint8_t, uint16_t, float |
— |
T (NEON) |
uint8_t |
NEON-only |
template<class T = uint8_t>
int bilateralFilter(
const T* srcImage, T* dstImage,
int width, int height, int cn,
int srcStride, int dstStride,
int d, double sigmaColor, double sigmaSpace,
const T* constant = nullptr,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const T* / T*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 or 3 |
srcStride, dstStride
|
int |
Bytes per row | required |
d |
int |
Filter radius (kernel = 2d+1) | ≥ 1 |
sigmaColor |
double |
Standard deviation in color space | typically 10-100 |
sigmaSpace |
double |
Standard deviation in coordinate space | typically 10-100 |
constant |
const T* |
BORDER_CONSTANT fill value |
nullptr |
bt |
acl::BorderType |
Border handling | BORDER_REFLECT_101 |
int bilateralFilter(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride, int dstStride,
int d, double sigmaColor, double sigmaSpace,
int constant = 0,
int cn = 1,
acl::BorderType bt = acl::BorderType::BORDER_REFLECT_101);cn = 1 or 3 (channel count, runtime).
uint8_t srcImage[1920*1080], dstImage[1920*1080];
// Edge-preserving denoising, d=5, sigmaColor=sigmaSpace=30
acl::neon::filter::bilateralFilter(
srcImage, dstImage, 1920, 1080, 0, 0, 5, 30.0, 30.0);Non-Local Means denoising — searches for similar patches within the entire search window and forms a weighted average, denoising while preserving details.
Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T (CPP) |
uint8_t, uint16_t, float |
— |
T (NEON) |
uint8_t |
NEON-only |
template<class T = uint8_t>
int nlMeansDenoising(
const T* srcImage, T* dstImage,
int width, int height,
int srcStride, int dstStride,
float h,
int patchRadius = 3,
int searchRadius = 10);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const T* / T*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
srcStride, dstStride
|
int |
Bytes per row | required |
h |
float |
Denoising strength (larger = smoother; typically 5-15) | required |
patchRadius |
int |
Patch radius (patch = 2r+1) |
3 (= 7×7) |
searchRadius |
int |
Search-window radius |
10 (= 21×21) |
int nlMeansDenoising(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride, int dstStride,
float h,
int patchRadius = 3,
int searchRadius = 10);Non-templated; the signature matches the CPP version with the template
<T>removed.
uint8_t srcImage[1920*1080], dstImage[1920*1080];
// Light denoising (h=10, patch 7×7, search 21×21 — defaults)
acl::neon::filter::nlMeansDenoising(srcImage, dstImage, 1920, 1080, 0, 0, 10.0f);
// Stronger denoising + larger search window
acl::neon::filter::nlMeansDenoising(srcImage, dstImage, 1920, 1080, 0, 0, 15.0f, 3, 15);Guided filter — edge-aware smoothing of the input image based on the guide image (guideImage). O(N) complexity (does not grow with kernel size).
Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T |
uint8_t, uint16_t, float |
— |
template<class T>
int guidedFilter(
const T* guideImage,
const T* srcImage,
T* dstImage,
int width, int height,
int guideStride, int srcStride, int dstStride,
int radius, double eps);| Parameter | Type | Meaning | Default |
|---|---|---|---|
guideImage |
const T* |
Guide image (often identical to srcImage; another image also works) | non-null |
srcImage, dstImage
|
const T* / T*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
guideStride, srcStride, dstStride
|
int |
Respective bytes per row | required |
radius |
int |
Window radius (window size = 2r+1) | ≥ 1 |
eps |
double |
Regularization parameter | typically 0.01 (integer images 1.0-100.0) |
int guidedFilter(
const uint8_t* guideImage,
const uint8_t* srcImage,
uint8_t* dstImage,
int width, int height,
int guideStride, int srcStride, int dstStride,
int radius, double eps);// Use the source image itself as the guide; radius=8, eps=1000
acl::filter::guidedFilter<uint8_t>(
srcImage, srcImage, dstImage, 1920, 1080, 1920, 1920, 1920, 8, 1000.0);O(1) approximate Gaussian blur (complexity independent of kernel size); suitable for large-kernel scenarios. The effect is close to Gaussian but slightly different; used where exact Gaussian is not required (e.g. UI blurred backgrounds).
Tier: Starter+
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T |
uint8_t, uint16_t, float |
— |
template<class T>
int stackBlur(
const T* srcImage, T* dstImage,
int width, int height, int cn,
int srcStride = 0, int dstStride = 0,
int kSizeX = 3, int kSizeY = 3);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const T* / T*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
cn |
int |
Channel count | 1 or 3 |
srcStride, dstStride
|
int |
Bytes per row |
0 = auto |
kSizeX, kSizeY
|
int |
Horizontal / vertical kernel size (must be odd) | 3 |
int stackBlur(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height, int cn,
int srcStride = 0, int dstStride = 0,
int kSizeX = 3, int kSizeY = 3);// 21×21 blur (well beyond Gaussian 11×11; the O(1) algorithm does not degrade)
acl::filter::stackBlur<uint8_t>(srcImage, dstImage, 1920, 1080, 1, 0, 0, 21, 21);Unsharp Mask — subtracts a blurred image from the source to produce a sharpening enhancement. amount controls the sharpening strength.
Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T |
uint8_t, uint16_t, float |
— |
template<class T>
int unsharpMask(
const T* srcImage, T* dstImage,
int width, int height,
int srcStride, int dstStride,
int kRadius, double sigma, float amount);| Parameter | Type | Meaning | Default |
|---|---|---|---|
srcImage, dstImage
|
const T* / T*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
srcStride, dstStride
|
int |
Bytes per row | required |
kRadius |
int |
Gaussian kernel radius | ≥ 1 |
sigma |
double |
Gaussian sigma (controls blur strength) | typically 1.0 ~ 2.0
|
amount |
float |
Sharpening strength | typically 0.5 ~ 2.0 (1.0 = original strength) |
int unsharpMask(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride, int dstStride,
int kRadius, double sigma, float amount);// Light sharpening (radius=2, sigma=1.5, amount=1.2)
acl::filter::unsharpMask<uint8_t>(
srcImage, dstImage, 1920, 1080, 0, 0, 2, 1.5, 1.2f);Gabor filter — sinusoidal × Gaussian-modulated kernel used for texture analysis and direction-sensitive edge detection.
Tier: Pro+
Channels: 1ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T |
uint8_t, uint16_t, float |
— |
template<class T>
int gaborFilter(
const T* srcImage, T* dstImage,
int width, int height,
int srcStride, int dstStride,
int ksize, double sigma, double theta,
double lambd, double gamma, double psi);| Parameter | Type | Meaning | Typical value |
|---|---|---|---|
srcImage, dstImage
|
const T* / T*
|
input / output | non-null |
width, height
|
int |
Image size | > 0 |
srcStride, dstStride
|
int |
Bytes per row | required |
ksize |
int |
Kernel size (typically odd) |
21 / 31
|
sigma |
double |
Gaussian envelope sigma |
4.0-8.0
|
theta |
double |
Direction (radians) |
0 (horizontal) ~ π
|
lambd |
double |
Sinusoidal wavelength | 10.0 |
gamma |
double |
Spatial aspect ratio | 0.5 |
psi |
double |
Phase offset | 0 |
int gaborFilter(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride, int dstStride,
int ksize, double sigma, double theta,
double lambd, double gamma, double psi);uint8_t srcImage[1920*1080], dstImage[1920*1080];
// Horizontal-direction Gabor kernel
acl::neon::filter::gaborFilter(srcImage, dstImage, 1920, 1080, 0, 0,
21, 4.0, 0.0, 10.0, 0.5, 0.0);Edge-preserving filtering — O(N) edge-preserving smoothing based on recursive domain transforms (Gastal & Oliveira, SIGGRAPH 2011).
edgePreservingFilter smooths while preserving edges; detailEnhance uses it in reverse to enhance details.
Tier: Business
Channels: 3ch (RGB)
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T |
uint8_t |
— |
int edgePreservingFilter(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
float sigmaS = 60.0f, float sigmaR = 0.4f,
int numIter = 3);
int detailEnhance(
const uint8_t* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
float sigmaS = 10.0f, float sigmaR = 0.15f);| Parameter | Type | Meaning | Default |
|---|---|---|---|
sigmaS |
float |
Spatial sigma (larger → larger smoothing range) | 60.0 (edge-preserving) / 10.0 (detail) |
sigmaR |
float |
Color-value sigma | 0.4 / 0.15 |
numIter |
int |
Number of iterations (edge-preserving) | 3 |
uint8_t rgbSrc[1920*1080*3], rgbDst[1920*1080*3];
// Cartoon-style effect
acl::filter::edgePreservingFilter(rgbSrc, rgbDst, 1920, 1080, 0, 0, 60.0f, 0.4f, 3);
// Detail enhancement
acl::filter::detailEnhance(rgbSrc, rgbDst, 1920, 1080);HDR tone mapping — compresses a float HDR image into the uint8_t LDR display space. Provides 3 classic algorithms.
Tier: Business
Channels: 1ch / 3ch
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
| Input | float |
— |
| Output | uint8_t |
— |
// Linear exposure (simple gamma)
int tonemapLinear(
const float* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
float gamma = 2.2f, float exposure = 1.0f);
// Reinhard (global key control)
int tonemapReinhard(
const float* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
float gamma = 2.2f,
float key = 0.18f,
float lWhite = 0.0f);
// Drago (logarithmic mapping, suitable for high dynamic range)
int tonemapDrago(
const float* srcImage, uint8_t* dstImage,
int width, int height,
int srcStride = 0, int dstStride = 0,
float gamma = 2.2f,
float saturation = 1.0f,
float bias = 0.85f);| Parameter | Meaning | Typical value |
|---|---|---|
gamma |
Output gamma correction | 2.2 |
exposure (Linear) |
Exposure multiplier | 1.0 |
key (Reinhard) |
Mean-luminance key | 0.18 |
lWhite (Reinhard) |
White point (0 = auto-take max) |
0.0 |
saturation (Drago) |
Saturation | 1.0 |
bias (Drago) |
Bias | 0.85 |
float hdr[1920*1080];
uint8_t ldr[1920*1080];
// Simplest: linear + gamma
acl::filter::tonemapLinear(hdr, ldr, 1920, 1080);
// Use Reinhard when the scene is too bright
acl::filter::tonemapReinhard(hdr, ldr, 1920, 1080, 0, 0, 2.2f, 0.18f);Multi-exposure image fusion (Mertens et al. 2007) — fuses multiple images at different exposures into a single balanced-exposure output. A simpler alternative to the HDR + tonemap pipeline.
Tier: Business
Channels: 3ch (RGB)
Inplace: not supported
Types:
| Template parameter | Allowed types | Constraint |
|---|---|---|
T |
uint8_t |
— |
int mergeMertens(
const uint8_t** images, int numImages,
uint8_t* dstImage,
int width, int height,
const int* strides = nullptr,
int dstStride = 0,
float wContrast = 1.0f,
float wSaturation = 1.0f,
float wExposure = 1.0f);| Parameter | Meaning | Typical value |
|---|---|---|
images |
Input image pointer array (3ch RGB) |
numImages images |
numImages |
Number of input images | typically 3 (underexposed / normal / overexposed) |
strides |
Per-image stride array; when nullptr, all treated as width*3
|
optional |
wContrast |
Contrast weight | 1.0 |
wSaturation |
Saturation weight | 1.0 |
wExposure |
Exposure-quality weight | 1.0 |
uint8_t under[1920*1080*3], normal[1920*1080*3], over[1920*1080*3];
uint8_t fused[1920*1080*3];
const uint8_t* imgs[3] = { under, normal, over };
acl::filter::mergeMertens(imgs, 3, fused, 1920, 1080);