sroush
sroush

Reputation: 6763

Imagemagick: how to whiteout every pixel that is not adjacent to a pixel of another color?

The input image is generated, so every pixel is an exact color. I am interested in the intersections of these colors, and the objects they define.
I want to whiteout every pixel that is adjacent only to pixels that are the same color or are already white. Pixels that are adjacent to pixel(s) of another color are unmodified.
i.e. The result should be just the points and/or edges where the red square is crossed by the green line. My guess is that morphology is involved using a square kernel. But am at a loss as to the method.

Before & After (approximated using "eraser") enter image description here and after
enter image description here

Worked with my simplistic example, but not so well with more realistic attempt:
enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

Two versions of real starting image (computer generated):
enter image description here enter image description here

Upvotes: 0

Views: 86

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207345

I haven't quite got my head around exactly what you want and I only have an iPhone to hand this week, so I'll try and get you as close as I can and you can work out the rest hopefully.

You seem to want all edges, that are not adjacent to white. So let's find:

  • all edges adjacent to white, and
  • all edges

then do some differencing.


So, for all edges adjacent to white, make everything not white become black, then find edges:

magick shapes.png -fill black +opaque white -canny 0x1+30% -negate whiteedges.png

Intermediate step

enter image description here

whiteedges.png

enter image description here


Now for all edges. Make everything into shades of grey and find all edges:

magick shapes.png -colorspace gray -canny 0x1+30% otheredges.png

Intermediate step

enter image description here

otheredges.png

enter image description here


Now combine the two, by multiplying, but there are other blend modes you can try:

magick whiteedges.png otheredges.png -compose multiply -composite result.png

enter image description here


You can obviously add thresholding to the edge-detected image to brighten the detected edges. You an also dilate the white areas to make them bigger/fatter, or erode them to make them thinner. You can also remove small artefacts with median filters and so on, but I think the mask is close to what you want.

We can also combine all the above into a single command if performance is important.


Say you wanted to fatten (dilate) the white parts with quite a large radius, you could use:

magick result.png -morphology dilate disk:5 fatBoy.png

enter image description here


If I now take that image and force it into your original image as the alpha/transparency layer:

magick shapes.png fatBoy.png -compose copyalpha -composite newResult.png

enter image description here

Or, we can clean up a little more by making white pixels transparent too:

magick shapes.png fatBoy.png -compose copyalpha -composite -transparent white newResult.png

enter image description here

Upvotes: 1

Related Questions