Write-mask not working with define connected components?

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?".
Post Reply
coloring
Posts: 82
Joined: 2015-08-27T10:17:36-07:00
Authentication code: 1151

Write-mask not working with define connected components?

Post by coloring »

Hi,

I have a mask, and also morphology edgeout from the mask. I want to remove unwanted black holes inside the edgeout, but since there may be holes I need to keep, I am trying to use a write-mask using the original alpha mask to keep the connected components code from removing parts I want to keep. Problem is, it's not working, and I don't know why. Am I doing it wrong, or is there another way to do this?

Mask
Image

Edgeout
Image

Connected components code

Code: Select all

-define connected-components:mean-color=true \
-define connected-components:area-threshold=500 \
-connected-components 4
What I'm trying to do

Code: Select all

-write-mask mask.png \
-define connected-components:mean-color=true \
-define connected-components:area-threshold=500 \
-connected-components 4 +write-mask
I'm using IM 7
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Write-mask not working with define connected components?

Post by fmw42 »

The two images appear to be exclusive of each other. Nevertheless, I am not sure if you can even use a write mask with -connected-components
coloring
Posts: 82
Joined: 2015-08-27T10:17:36-07:00
Authentication code: 1151

Re: Write-mask not working with define connected components?

Post by coloring »

Yes, it seems to not be compatible. Write mask works for me in other areas

My other idea to pursue is to overlay the mask image onto the edgeout (which will leave only the unwanted holes), use define to remove the holes, then use the mask again to cut out the original part in the edgeout. Is it viable? Currently working on figuring out how to do this (I'm still new, don't know much)

My current code:

Code: Select all

border=25
octagon=20
fuzz=0
blur=2x20
threshold=500

magick \( $1 +repage -bordercolor white -border 1x1 \
-fuzz $fuzz% -fill transparent -floodfill +0+0 white -shave 1x1 \
-bordercolor transparent -border ${border}x${border} \) \
\( -clone 0 -fill white -colorize 100% \) \
\( -clone 0 -alpha extract +write tmp0.png -write mpr:alpha -morphology edgeout octagon:$octagon \
-define connected-components:mean-color=true \
-define connected-components:area-threshold=$threshold \
-connected-components 4 \
+write tmp1.png \) \
-alpha off -compose over -composite +write tmp2.png \
\( mpr:alpha -morphology dilate octagon:$octagon \
-define connected-components:mean-color=true \
-define connected-components:area-threshold=$threshold \
-connected-components 4  -blur $blur -level 50x100% +write tmp3.png \) \
-alpha off -compose copy_opacity -composite -trim \
$1.gif
Current image used for testing
Image
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Write-mask not working with define connected components?

Post by fmw42 »

What do you get left in the image if you must use connected components that you do not want or that you want to preserve.
coloring
Posts: 82
Joined: 2015-08-27T10:17:36-07:00
Authentication code: 1151

Re: Write-mask not working with define connected components?

Post by coloring »

This is an image from later in the process, but you can see that the edgeout effect from earlier had created an enclosed area, and thus created an unintended "hole" (depending on the image, it can be much worse than this), which is left in the image's final result (as you can see, we can find and remove the hole because we have a mask of the areas we want to keep).

I realized that I couldn't remove just any gap in the image, because there are some pieces which need to stay. So I have to differentiate what to keep before using define

Image

And using define without first accounting for the areas I want to keep would result in this. See how the unintended hole is gone, but it also filled in the areas I wanted
Image
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Write-mask not working with define connected components?

Post by fmw42 »

Why not just use -morphology close on your first image above to remove the small hole
coloring
Posts: 82
Joined: 2015-08-27T10:17:36-07:00
Authentication code: 1151

Re: Write-mask not working with define connected components?

Post by coloring »

From my limited understanding and what I've read in the docs, it seems that I need to do a morphology close on a extracted alpha copy (not sure what to call that). So I still need to:
1, figure out how to first combine the alpha extracted copy with the edge image to create a complete white mask (except for the holes I want to get rid of)
2, remove the holes (using the define code, or morphology close as you suggested)
3, use the mask again to make those parts black (make it the way it was originally)

P.S. I tried morphology close on the first image, and it didn't turn out pretty
Image
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Write-mask not working with define connected components?

Post by fmw42 »

If you increased the area-threshold just a small amount (I guess in your edge out image), it would have removed that one tiny hole in the first image from your previous post.

I guess I really do not know what you are trying to do. Can you show the start image and one processed and point out what you are trying to do and what is wrong.
coloring
Posts: 82
Joined: 2015-08-27T10:17:36-07:00
Authentication code: 1151

Re: Write-mask not working with define connected components?

Post by coloring »

Forgive me, I've never done any image work, ever, and I'm also completely new to IM. Still trying to explain it best I can and figure it out.

Start image
Image

End current result (see the gap inside?)
Image

What I actually want (little gap is gone). Other images have bigger gaps that I want to remove. So the threshold needs to be big enough. The point is, remove anything that isn't supposed to be there.
Image

Code

Code: Select all

border=40
octagon=20
fuzz=0
blur=2x20
threshold=500

magick \( $1 +repage -bordercolor white -border 1x1 \
-fuzz $fuzz% -fill transparent -floodfill +0+0 white -shave 1x1 \
-bordercolor transparent -border ${border}x${border} \) \
\( -clone 0 -fill white -colorize 100% \) \
\( -clone 0 -alpha extract +write tmp0.png -write mpr:alpha -morphology edgeout octagon:$octagon +write tmp1.png \) \
-alpha off -compose over -composite +write tmp2.png \
\( mpr:alpha -morphology dilate octagon:$octagon \
-blur $blur -level 50x100% +write tmp3.png \) \
-alpha off -compose copy_opacity -composite -trim \
$1.gif
---------

Problem: there's a lot of other holes in the image I want to keep (the waterdrops), but still remove the gap that shouldn't be there
Image

And removing all the gaps would remove my water drops too
Image

My intended solution:
After the morphology edgeout code, use a write-mask right before the define connected code

Code: Select all

-morphology edgeout octagon:$octagon \
-write-mask mpr:alpha -define connected-components:mean-color=true \
-define connected-components:area-threshold=$threshold \
-connected-components 4 +write-mask
Problem, that didn't work. My next idea to solve it, is
1, overlay the alpha extraction (mpr:alpha) on top of the morphology edgeout image (this will make the inside completely white, except for the holes I want to remove)

It would look likes this:
Image

2, remove the holes with the define connected (actually, I can use morphology close here now at this point since it won't have unintended side effects)

This would give this
Image

3, use the alpha extraction to again cut out (turn black) the inside, just like the original edgeout will look, but minus the hole I don't want

This would result in the (see how the gap is now gone)
Image


I don't know if this is the best way to approach this problem, but it's the best I can think of. I also don't know yet how to do what I want to (what I said above), because I'm still new, and still reading the docs. Is this the best way to accomplish my goal? Any other way? How would I do it?

I hope I explained clearly enough for you this time :)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Write-mask not working with define connected components?

Post by fmw42 »

Something is wrong with your processing since the images are not the same size. But it seems that the following would do what you want, if you fix the sizing (probably remove the padding you might have added - see -shave). Just multiply the original with the mask from step 2.

Code: Select all

convert bitmoji432844786.png storage_emulated_0_Android_data_com_bitstrips_imoji_cache_tmp1_2.png +repage -compose multiply -composite result.png
coloring
Posts: 82
Joined: 2015-08-27T10:17:36-07:00
Authentication code: 1151

Re: Write-mask not working with define connected components?

Post by coloring »

My solution

Line 1, create mask from image, do morphology edgeout
2, replace the background black with transparent on the mask
3, combine the mask with the edgeout in order to show only holes that shouldn't be there
4, fill the entire background with white to reveal only the holes to fill in (which will be black), and negate it to make the black white (entire image will turn transparent unless you use alpha off)
5, replace the background (now black because of negate) with transparent, leaving only white holes to be replaced
6, overlay it over the morphology edge image, thus eliminating the unwanted holes

Code: Select all

\( -clone 0 -alpha extract +write $idir/tmp0.png -write mpr:alpha -morphology edgeout octagon:$octagon -write mpr:edge +write $idir/tmp1.png \
mpr:alpha -fill transparent -floodfill +0+0 black \
-compose over -composite +write $idir/tmp2.png \
-fill white -floodfill +0+0 transparent -alpha off -negate +write $idir/tmp3.png  \
-fill transparent -floodfill +0+0 black -write mpr:chunk +write $idir/tmp4.png \
mpr:edge -compose dst_over -composite +write $idir/tmp5.png \) \
Full code

Code: Select all

magick \( $1 +repage -bordercolor white -border 1x1 \
-fuzz $fuzz% -fill transparent -floodfill +0+0 white -shave 1x1 \
-bordercolor transparent -border ${border}x${border} \) \
\( -clone 0 -fill white -colorize 100% \) \
\( -clone 0 -alpha extract +write $idir/tmp0.png -write mpr:alpha -morphology edgeout octagon:$octagon -write mpr:edge +write $idir/tmp1.png \
mpr:alpha -fill transparent -floodfill +0+0 black \
-compose over -composite +write $idir/tmp2.png \
-fill white -floodfill +0+0 transparent -alpha off -negate +write $idir/tmp3.png  \
-fill transparent -floodfill +0+0 black -write mpr:chunk +write $idir/tmp4.png \
mpr:edge -compose dst_over -composite +write $idir/tmp5.png \) \
-alpha off -compose over -composite +write $idir/tmp6.png \
\( mpr:alpha mpr:chunk -compose over -composite \
-morphology dilate octagon:$octagon  \
-blur $blur -level 50x100% +write $idir/tmp7.png \) \
-alpha off -compose copy_opacity -composite -trim  +repage \
$1.gif
Source image
Image

tmp0
Image

tmp1
Image

tmp2
Image

tmp3
Image

tmp4
Image

tmp5 (as opposed to tmp1)
Image

tmp6
Image

tmp7
Image

Final result
Image

How it would've looked without replaced holes
Image

There may be a better and more efficient way to do this .... Let me know if you have any ideas to streamline it. At least I have a working example now though
Post Reply