Steve on Image Processing

March 23rd, 2007

Pad values in dilation and erosion

Blog reader DKS asked recently why values outside the image are assumed to be -Inf when computing dilation. I thought this issue was worth exploring further because it has practical implications for certain computations.

Suppose we start with a simple 4-by-4 matrix:

f = [22 23 15 16; 24 25 14 15; 20 18 17 23; 19 16 15 20]
f =

    22    23    15    16
    24    25    14    15
    20    18    17    23
    19    16    15    20

Now think about computing the erosion with a 3-by-3 flat structuring element. What's the output at the upper left corner? It's the minimum of these 9 values:

?? ?? ??
?? 22 23
?? 24 25

So what do we use for the unknown values outside the image boundary? Suppose we zero pad:

 0  0  0
 0 22 23
 0 24 25

Then the (1,1) output value is 0. In fact, if the image pixels are nonnegative, which is common, there will be a zero-valued one-pixel-wide border all the way around the edge of the output image. This is called a boundary artifact and is undesirable. We could avoid this problem by simply excluding external values in our computation of the minimum. A mathematical equivalent for erosion is to assume external values all equal some constant that is guaranteed to be greater than or equal to all image pixels - like Inf:

Inf Inf Inf
Inf  22  23
Inf  24  25

To avoid boundary artifacts when performing dilation, pad with -Inf:

-Inf -Inf -Inf
-Inf   22   23
-Inf   24   25

Most of the time you don't need to explicitly use the Inf values. One type of exception occurs when the structuring element doesn't include the center element. Then sometimes the Inf values can appear in the output.

imdilate(f, [1 0 0])
ans =

    23    15    16  -Inf
    25    14    15  -Inf
    18    17    23  -Inf
    16    15    20  -Inf

Similarly, most of the time you don't actually need to explicitly pad the image. The exception is when you are computing a sequence of dilations (or erosions). In the Image Processing Toolbox this frequently occurs because imdilate and imerode exploit ''structuring element decomposition.'' That is, a large structuring element is decomposed into two or more smaller structuring elements that are mathematically equivalent to the original.

Here's a contrived example to demonstrate why you need to pad explicitly to make the mathematical equivalence work out.

Structuring element 1 translates an image to the left by 2 pixels.

se1 = [1 0 0 0 0];

Structuring element 2 translates an image to the right by 1 pixel.

se2 = [0 0 1];

You'd expect the composition of dilation with these two structuring elements to be equivalent to a single dilation with a structuring element that translates an image left by 1 pixel:

se3 = [1 0 0];

Let's try that sequence with no padding:

f1 = imdilate(f, se1)
f1 =

    15    16  -Inf  -Inf
    14    15  -Inf  -Inf
    17    23  -Inf  -Inf
    15    20  -Inf  -Inf

f2 = imdilate(f1, se2)
f2 =

  -Inf    15    16  -Inf
  -Inf    14    15  -Inf
  -Inf    17    23  -Inf
  -Inf    15    20  -Inf

Now dilate the original image with se3 and compare:

f3 = imdilate(f, se3)
f3 =

    23    15    16  -Inf
    25    14    15  -Inf
    18    17    23  -Inf
    16    15    20  -Inf

They aren't the same. To make the results equivalent, you have to pad the original image, perform the dilation sequence, and the crop the result.

fp = padarray(f, [2 2], -Inf)
fp =

  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf    22    23    15    16  -Inf  -Inf
  -Inf  -Inf    24    25    14    15  -Inf  -Inf
  -Inf  -Inf    20    18    17    23  -Inf  -Inf
  -Inf  -Inf    19    16    15    20  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf

fp1 = imdilate(fp, se1)
fp1 =

  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
    22    23    15    16  -Inf  -Inf  -Inf  -Inf
    24    25    14    15  -Inf  -Inf  -Inf  -Inf
    20    18    17    23  -Inf  -Inf  -Inf  -Inf
    19    16    15    20  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf

fp2 = imdilate(fp1, se2)
fp2 =

  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf    22    23    15    16  -Inf  -Inf  -Inf
  -Inf    24    25    14    15  -Inf  -Inf  -Inf
  -Inf    20    18    17    23  -Inf  -Inf  -Inf
  -Inf    19    16    15    20  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf
  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf  -Inf

fp2_cropped = fp2(3:end-2, 3:end-2)
fp2_cropped =

    23    15    16  -Inf
    25    14    15  -Inf
    18    17    23  -Inf
    16    15    20  -Inf

isequal(f3, fp2_cropped)
ans =

     1

Whenever imdilate or imerode is called with a decomposed structuring element, the functions compute the minimum padding necessary to avoid boundary artifacts and pad with either -Inf or Inf, respectively.

It's a classic speed vs. memory tradeoff. Exploiting structuring element decomposition is faster, but storing the intermediate padded arrays takes more memory.


Get the MATLAB code

Published with MATLAB® 7.4

4 Responses to “Pad values in dilation and erosion”

  1. Eric replied on :

    I am working with medical image segmentation software specifically for calcifications in coronary arteries. Our simulations use circular calcifications that I’d like to use image segmentation to characterize. It’s my understanding that the ideal structural element to use for morphology (imopen etc..) is a circular structuring element. I’ve noticed that MATLAB seems to be missing this feature 2007a (student).

    I was wondering about circular structuring elements. Is there a way to choose settings for the MATLAB disk structuring element to get a circle?

    Also is there a way to imshow(structureing_element) so I could visually verify it’s circular. The thing is that imshow doesn’t seem to like structuring elements.

    Thank you!

    -Eric

  2. Steve replied on :

    Eric—”Ideal” by what criterion? Every common structuring element shape has its own valid uses. strel(’disk’,…) is intended to be used to create a “circular” structuring element. However, by default it creates a structuring element that is only approximately circular. It does this in order to make a decomposed structuring element that is much faster to compute. Use strel(’disk’,R,0) to get a true circular structuring element. Just keep in mind that computing dilations and erosions with it will be slower. Use imshow(getnhood(se)) to display the structuring element neighborhood as an image.

  3. Jogging replied on :

    Hi, Steve
    I don’t understand the result of imdilate
    (f, [1 0 0]).Take 23 of the first row,
    the output should be the maximum value of all
    the pixels in the input pixel’s neighborhood
    under the structuring element.The neighbors are
    22 23 15, and the structuring element is
    1 0 0.So the neighbor used for compute maximum
    value should only be 22. So the output should be
    22.But the matlab gives the output of 15.
    I can’t explain it.

    Best Regards
    Jogging

  4. Steve replied on :

    Similar to convolution, in dilation the structuring element is reflected through its center (rotated 180 degrees) before the max operation is applied. This definition of dilation is common but not universal. I believe it is more common in Europe to define dilation without the reflection.

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Steve Eddins manages the Image & Geospatial development team at The MathWorks and coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

  • murat: Hi Steve, I have an rgb image of a kind of cream and it contains some small black particles (black dots). In...
  • Steve: Ernest—Look at setting the FaceColor property. The code for setting that is shown on the page you asked...
  • Ernest Miller: Hi Steve, Understood. However, can you explain how to change the colors? Thanks, Ernest
  • Jan: Hi Steve Very useful code, yet what if I parts of my rotated+translated object are outside the original...
  • Steve: MoHDa—It might be possible. You’ll need to use one of the options that produces closed edge...
  • MoHDa: I have one question about the ROIPOLY: I have an image with stripes, I use the “edge” command for...
  • Steve: Shahn—My November 17, 2006 post shows you how to do it.
  • Steve: Kay-Uwe—Thanks for following up. I am planning to make it easier to use test directories in a package....
  • shahn: Hello Steve Instead of superimposing a star on the image to show the centroide. How would you superimpose a...
  • Kay-Uwe: Having TestSuite.fromPackag e() would be nice to have, but so far using simple “test” subdirs...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.