Log in

View Full Version : remove isolated dots in a mask.


mathmax
18th December 2011, 19:08
Hi

I would like to remove the spots under a certain size (amount of pixels) in a mask. Is there some function to achieve this in masktool?

thanks

cretindesalpes
18th December 2011, 19:58
Depending on your mask, a single mt_deflate() can remove single pixels. However, it will modify the original mask. For larger blocks (2x2 pixels), use mt_inpand() followed by an mt_expand(). Again, the mask will be slightly changed.

If you want something really accurate, use:
x = mt_hysteresis (mt_deflate (), last)
mt_merge (x, last, x)
Replace mt_deflate() with one or more mt_inpand() to eliminate larger blocks.

If you want to remove pixel-sized holes in the mask, enclose the code between two mt_invert().

Gavino
18th December 2011, 20:31
That reminds me to ask something that's been at the back of my mind for a while.

I'm fairly well up to speed on most masktools functions, but I've never really understood what mt_inflate, mt_deflate and mt_hysteresis actually do, and what they're useful for. Can anyone give a simple explanation?

cretindesalpes
18th December 2011, 21:03
From the doc:
mt_inflate/mt_deflate: It computes a local average by taking into account only the neighbourgh whose value is higher/lower than the pixel.
It helps growing or shrinking a mask by a smaller amount than mt_expand/mt_inpand (something like half-pixel accuracy). However their effect is not cumulative, cascading xxflate functions will not grow or shrink the mask proportionally.

mt_hysteresis will keep each solid areas of the second mask depending if there is at least one pixel of the first mask in these areas. It's like a fill function trying to color the second mask from each pixel set in the first mask. Masks are considered as binary, so you'll need some mt_merge wizardry to restore the shades of grey. What asked the OP is an excellent example of use for mt_hysteresis: shrink the mask to remove the smallest elements and restore the exact shape of the remaining parts with mt_hysteresis.

mathmax
18th December 2011, 21:10
Thank you :)

In fact, I came to something pretty similar in the meantime:


conv = c.mt_convolution("1 2 1", "1 1 1 1 1")
cleaned = conv.binarize(128, false)
mt_hysteresis(cleaned, c)

That is because I wanted to favour the verticality, which means a long vertical spot should be kept even if thin, but a horizontal one should be dropped.

Gavino, this thread give a simple example on how mt_hysteresis() works :
http://forum.doom9.org/showthread.php?t=128458


Now I'm wondering how to drop the spots that have more than a certain width... any idea?

Didée
18th December 2011, 21:23
Remove single dots: Removegrain(1)

remove 1x2 spots: Removegrain(2)

remove 3pixel-clusters: Removegrain(3)

remove up to 2x2-pixel-clusters: Removegrain(4)


Also, I think the explanation for in/deflate mt_inflate/mt_deflate: It computes a local average by taking into account only the neighbourgh whose value is higher/lower than the pixel. has been wrong ever since. The average is computed by all 8 (or 9?) pixels of the 3x3 neighborhood. Then, the result applies if and only if the the average is darker (deflate) or brighter (inflate) than the original pixel. (Per the quoted description, in/deflate would be almost the same as ex/inpand.)

cretindesalpes
18th December 2011, 23:35
Removegrain
Oh yes this is much simpler like that!

mathmax
20th December 2011, 00:39
hi again

Is there a way to have the position of a pixel in the expression given to mt_lut() ?