0

I would like to dilate an image using a different kernel at each pixel. I was wondering if opencv supported this before I implement it myself.

Essentially, I want to perform dilation with an ellipse structural element that is rotated depending on where it is in the image. So that the ellipse is a function of the pixel i.e get_ellipse_rotation(pixel_x, pixel_y).

Cedric Martens
  • 1,139
  • 10
  • 23
  • 2
    please pick a language. I hope it's Python. (1) not that I know of. best you can do is list your different kernels, apply each to the whole image, and then compose according to which you want for each pixel. if the set of kernels is large, you'd have to resort to literally performing the operation per pixel, by hand. python: numba. (2) one arbitrary but constant kernel, across the whole image, is trivial. just don't trust the `getStructuringElement` to give you nicely shaped ellipses. it's even terrible at circles. – Christoph Rackwitz Apr 09 '23 at 13:31

1 Answers1

0

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).

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36