Jorge Vega Sánchez
Jorge Vega Sánchez

Reputation: 7590

Dilate/erode modify kernel option

I want to smooth the contour of binarized images and think that erode is the best way to do it. I know that normal way of work is use cvDilate(src, dst, 0, iter); where 0 is a 3x3 matrix.

Problem is 3x3 matrix makes a deep erode in my images. How can I do a erode with a 2x2 matrix or anything smaller than the default 3x3 matrix.

Upvotes: 9

Views: 18271

Answers (6)

Adam Freeman
Adam Freeman

Reputation: 1278

A kernel with all 1's is a low pass convolution filter. A dilation filter replaces each pixel in the 3X3 region with the darkest pixel in that 3x3 region. An erosion filter replaces each pixel in the 3X3 region with the lightest pixel in that 3x3 region. That is if your background is light and your foreground object is dark. If you flip your background and foreground, then you would also flip your dilation and erosion filter.

Also if you want to perform an 'open' operation, you perform an erosion followed by a dilation. Conversely a 'close' operation is a dilation followed by an erosion. Open tends to remove isolated clumps of pixels and close tends to fill in holes.

Upvotes: 1

Shanil Jevin
Shanil Jevin

Reputation: 45

Errosion and dilation matrices should be odd order

-- a 2*2 matrix cannot be used

convolution matrices should be of the order 1*1 3*3 5*5 7*7 ... but ODD

try to apply close - Erode then dilate the image operation - use the cvMorpologyEx() function

Upvotes: 0

Dr. belisarius
Dr. belisarius

Reputation: 61046

Here you have for your reference the results of using different kernels:

enter image description here

Saludos!

Upvotes: 22

mpenkov
mpenkov

Reputation: 21904

Here's a quick and dirty approach to tell you whether dilation/erosion will work for you:

  • Upsample your image.
  • Erode (dilate, open, close, whatever) with the smallest filter you can use (typically 3x3)
  • Downsample back to the original image size

Upvotes: 3

jilles de wit
jilles de wit

Reputation: 7148

If your goals is to have a binarized image with smooth edges then, if you have the original, it is better to use something like a gaussian blur with cvSmooth() on that before performing the binarization.

That said, you are not restricted to 3x3 kernels. cvDilate() takes an IplConvKernel produced by CreateStructuringElementEx and you can make a structuring element with any (rectangular) shape with that function. However, a structuring element works relative to an anchor point that must have integer coordinates, so if you use a 2x2 matrix the matrix can not be centered around the pixel. so in most cases it is best to use structuring elements with an odd number of rows and collumns.

What you could do is create a 3x3 structuring element where only the center value and the values directly above, below, left and to the right of that are 1 like such:

0 1 0
1 1 1
0 1 0

rather than the default:

1 1 1
1 1 1
1 1 1

The first kernel will make for some slightly smoother edges.

Upvotes: 4

With the C API, you can create a dedicated IplConvKernel object of any kind and size with the function CreateStructuringElementEx(). If you to use the C++ API (function dilate()), the structuring element used for dilation is any matrix (Mat) you want.

Upvotes: 1

Related Questions