Reputation: 7590
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
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
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
Reputation: 61046
Here you have for your reference the results of using different kernels:
Saludos!
Upvotes: 22
Reputation: 21904
Here's a quick and dirty approach to tell you whether dilation/erosion will work for you:
Upvotes: 3
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
Reputation: 2033
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