luispedro / mahotas

Computer Vision in Python
https://mahotas.rtfd.io
Other
839 stars 147 forks source link

Erode/DIlate invent pixel values #37

Closed kannitverstan closed 10 years ago

kannitverstan commented 10 years ago

Hi,

I greatly appreciate your software! It is very well thought out and extremely useful.

Besides of that, I'm pretty sure I have found a bug in erode/dilate. I have attached the TEST.PNG plus the python test file below.

As I understand erosion/dilation, it is the min or max of the local neighbourhood. So it should not produce new pixel values which are not contained in the original image, right?

See attached python file with image. I also cross checked with the scpiy ndimage version, which does not produce the problem.

Regards, Clemens Steckner test

import mahotas im= mahotas.imread('test.png')

find list of all values of pixels gt 0

def pixelvalues(imi): im=imi.copy() lst=[] mn=im.min() while True: val= im.max() assert (im==val).any() if val == mn: break lst.append(val) im[im==val] = mn assert (im==mn).all() lst.append(mn) return [i for i in lst if i > 0]

show pixelvalues which have been 'invented' by mahotas

print set(pixelvalues(mahotas.erode(im))) - set(pixelvalues(im)) print set(pixelvalues(mahotas.dilate(im))) - set(pixelvalues(im))

erode invents pixel value 254

print (mahotas.erode(im) == 254).any(), (im==254).any()

dilate invents pixel value 103

print (mahotas.dilate(im) == 103).any(), (im==103).any()

luispedro commented 10 years ago

I don't like this interface 100%, but I adopted it from pymorph (scipy has the same, though).

from scipy import ndimage
cross = np.zeros((3,3), np.uint8)
cross[1] = 1
cross.T[1] = 1
set(pixelvalues(ndimage.grey_dilation(im, structure=cross))) - set(pixelvalues(im))

prints {103}

 set(pixelvalues(ndimage.grey_erosion(im, structure=cross))) - set(pixelvalues(im))

prints {0, 254}.

*

I think this is a duplicate of #29, so I'm closing here, but I still agree that the issue is confusing.

luispedro commented 10 years ago

If you do want local maxima/minima, there is a function mahotas.morph.locmax which does take a structuring element defining a region. Perhaps check that out.