OpenCV does not support a kernel that changes across the image.
You have a few options:
Number of different kernels is small
Then you can filter the image with each kernel separately, then use masking operations to compose a grand total, taking some pixels from each partial result.
Unbounded number of different kernels
You're left with calculating the filter result for each pixel yourself.
In other libraries that do convolution or anything sliding-window, there's the concept of full/same/valid
. You could take a slice of the whole image sized identically to the kernel, and get a single filter application, as a primitive operation to build the whole program. OpenCV's dilate()
sadly doesn't appear to have a parameter that modulates this. The BorderTypes
values only affect the calculation, not the domain. It's always same
. You can look at numpy and scipy, or write your own dilation code (see below).
OpenCV's getStructuringElement()
can produce some types of kernel but its results for ellipses and circles are ugly as sin. If you want a rotated ellipse, the ellipse()
call can probably do that to your satisfaction. Explore the LINE_AA
flag and shift
parameter.
If you write Python code, look at numba
. Custom loops, with @nb.jit
or @nb.njit
, can be faster than numpy routines. Numpy routines are necessarily general, hence not optimized for specific applications (dtypes etc).