How to dilate foreground only if it's surrounded by background?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
nicolai.rostov
Posts: 18
Joined: 2015-10-06T10:42:17-07:00
Authentication code: 1151

How to dilate foreground only if it's surrounded by background?

Post by nicolai.rostov »

How can I use the morphology operator to (i) enlarge an internal foreground (white) disk without (ii) shrinking the enclosing background (black) circle?

Image

With the dilate method I am able to enlarge the internal disk.

Code: Select all

convert input.pbm -morphology dilate disk:10 show:
Image

How can I do this without shrinking the black circle around it? More generally, how to can I dilate some foreground only if it is completly surrounded by background?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

What is your IM version and platform? Please always provide that information.

In Unix syntax:

Code: Select all

convert input.png \
\( +clone -morphology dilate disk:10 \
-fuzz 90% -fill black -draw "color 0,0 floodfill" -alpha off \) \
-compose plus -composite result.png
In Windows syntax:

Code: Select all

convert input.png ^
( +clone -morphology dilate disk:10 ^
-fuzz 90% -fill black -draw "color 0,0 floodfill" -alpha off ) ^
-compose plus -composite result.png
nicolai.rostov
Posts: 18
Joined: 2015-10-06T10:42:17-07:00
Authentication code: 1151

Re: How to dilate foreground only if it's surrounded by background?

Post by nicolai.rostov »

Thank you!
nicolai.rostov
Posts: 18
Joined: 2015-10-06T10:42:17-07:00
Authentication code: 1151

Re: How to dilate foreground only if it's surrounded by background?

Post by nicolai.rostov »

Thanks again. Using floodfill and compose works pretty well but it turns out, however, to be a bit expensive for dilating smaller, say, 1 to 3-pixel wide foreground points in images having many such white points.

Could you teach me how to define a morphology kernel that operates on such 1 to 3 pixel wide foreground which is complety enclosed in background, please?

For example, I'm looking for a kernel that, like the diamond, is able to dilate a point like this:

ImageImage

But, unlink the diamond, not this:

Image

Actually, a better, working, example would be this:

Image

I'm looking for a way to dilate the white point in the middle, without meddling with the white foreground outside.

ImageMagick 6.7.7-10 (Linux)
nicolai.rostov
Posts: 18
Joined: 2015-10-06T10:42:17-07:00
Authentication code: 1151

Re: How to dilate foreground only if it's surrounded by background?

Post by nicolai.rostov »

Okay, I think I got it.
The trick perhaps is to use the original image as its own mask!

Code: Select all

convert pixel.gif -mask pixel.gif -morphology dilate diamond +mask show:

Image

But this doesn't work for diamond:2, though. :(

Code: Select all

convert pixel.gif -mask pixel.gif -morphology dilate diamond:2 +mask show:
Image

I wonder why not. Since the enclosing white area is supposed to be protected by a mask. :?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

Try this, same technique as before.

Code: Select all

convert pixel.gif \
\( +clone -morphology dilate diamond:2 \
-fuzz 90% -fill black -draw "color 0,0 floodfill" -alpha off \) \
-compose plus -composite result.gif
nicolai.rostov
Posts: 18
Joined: 2015-10-06T10:42:17-07:00
Authentication code: 1151

Re: How to dilate foreground only if it's surrounded by background?

Post by nicolai.rostov »

Okay, you win. :D In order to make your code shorter, it's safe to drop

Code: Select all

-fuzz 90%
and

Code: Select all

-alpha off
when working with 1-bit, black and white, images, isn't it?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

If the image is truly 1-bit, then you can drop both.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

What is your IM version and platform? Please always provide that. If you are on IM 7, then possibly a read mask may work. IM 6 only has write masks. That is why your method does not work. But I am not sure even a read mask will protect the boundary pixels from the morphology processing.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

I just tested the read-mask in IM 7 and it does not protect the boundary pixels. So my -compose plus method seems to be the best method I know. But others may have better ideas.
nicolai.rostov
Posts: 18
Joined: 2015-10-06T10:42:17-07:00
Authentication code: 1151

Re: How to dilate foreground only if it's surrounded by background?

Post by nicolai.rostov »

Thanks for having checked IM 7 for me. I'm using ImageMagick 6.7.7-10, Linux, (see bottom of message #4 above).

I see your point. Boundary black pixels are affected by a morphology process that is triggered by white pixels covered by a mask that only protects them for writing.

Is it not possible to define some kind of conditional morphology kernel, which would select an area only if, not just if, it matches some criterion?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

I do not think IM morphology has that kind of capability. IM morphology kernels do not allow conditionals. You can only supply numerical values or NAN in a rectangular area. NAN means ignore, so that you are in effect making a non-rectangular shape.

I think you misunderstand how morphology works. It is not a point operator. I looks at all the pixels in a region around each pixel in the image to decide what to do. So it does not stop at the boundary of a mask. The mask boundary pixels when processed by the morphology kernels include pixels that go outside the boundary. That is why the mask does not help.

What kind of conditional do you have in mind that would resolve your problem? Can you state the condition? What would distinguish the center pixel and its neighbors from any other white pixel with neighboring black pixels?

Dilate essentially looks at each pixel and changes black pixels to white if there are any white neighbors. It changes the center pixel to the maximum value of the pixels in the neighborhood (kernel) region.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

Here is another way. If you create a mask that is larger than dilated center region and smaller than the area of the black, then you can use a mask. Here I draw a black circle the size of the dilated region on a white background.

Code: Select all

convert pixel.gif \
	\( -clone 0 -evaluate set 100% \
	-fill black -draw "translate 9,10 circle 0,0 0,2" \
	+write mpr:mask +delete \) \
-mask mpr:mask -morphology dilate diamond:2 +mask tmp.gif
The downside is that it has more commands than my previous one and you have to know where the inner white pixel is located (or be able to find its coordinates).
nicolai.rostov
Posts: 18
Joined: 2015-10-06T10:42:17-07:00
Authentication code: 1151

Re: How to dilate foreground only if it's surrounded by background?

Post by nicolai.rostov »

You're right. I still don't fully understand how morphology, and especially the kernels, work. But, as you said, if it "looks at all the pixels in a region around each pixel in the image to decide what to do", I wonder if it could, by looking at those same pixels, decide not just what to do but also what not to do.

Let me see if I'm able to express what I mean.

Consider kernel A:

Code: Select all

5x3: nan,1,1,1,nan   1,1,1,1,1   nan,1,1,1,nan
Suppose that, in addition to nan, 0, and 1, we had 2 and 3, where 2 means "must be background", and 3 means "must be foreground". Then, a hypothetical kernel B like this:

Code: Select all

5x3:
     2,2,2,2,2
 2,nan,1,1,1,nan,2
   2,1,1,1,1,1,2
 2¸nan,1,1,1,nan,2
     2,2,2,2,2
would do whatever A does to a region provided that pixels around it be all background, otherwise it would just skip it.

Not sure if this makes any sense. IM's documentation (http://www.imagemagick.org/Usage/morphology/#user) on morphology, for all the effort that has been put in it, is not particularly easy to follow if one is not already familiar with the literature about it.
Last edited by nicolai.rostov on 2016-10-01T17:42:29-07:00, edited 1 time in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to dilate foreground only if it's surrounded by background?

Post by fmw42 »

How do you define foreground and background when you have an inner white, a middle black and an outer white? Do you mean black vs white? But more importantly, morphology applies also to grayscale images and not just binary. So what would the background and foreground be in those cases.

I suppose anything can be coded if clearly defined, but IM does not currently have such features. It is not likely that this kind of enhancement will be added in the near future. But I am not a developer and will leave those decisions to the developers.
Post Reply