[Image-SIG] morphological functions
Robert Klimek
klimek@grc.nasa.gov
Mon, 8 Jul 2002 17:32:08 -0400
On Monday 24 June 2002 05:27 pm, you wrote:
> I need to add some morphological function capability to my PIL based
> program, such as erosion, dilation, hole fill, border, and skeletonizin=
g.
> I'd rather not re-invent the wheel if I don't have to. So, does anybody
> have and this written and are willing to share the code?
>
For those interested, I've written a couple of PIL-based functions that=20
perform a 4-point erosion and dilation and I thought I'd share the code. =
Note=20
that these functions work only on thresholded images (not on general=20
grayscale). These functions are fairly fast., compared to my earlier atte=
mpts=20
where I looped through all the pixels in the image getting min of a 3x3=20
neighborhood.
Bob
def erode(image):
paddedImage =3D createPaddedImage(image, 1)
thresholdImg =3D paddedImage.point(lambda i, v=3D128: i > v and 255)
filteredImg =3D thresholdImg.filter(ImageFilter.FIND_EDGES)
thresholdImg =3D filteredImg.point(lambda i, v=3D128: i > v and 255)
arithImg =3D ImageChops.subtract(paddedImage, thresholdImg)
box =3D (1, 1, arithImg.size[0]-1, arithImg.size[1]-1)
outImage =3D arithImg.crop(box)
return outImage
def dilate(image):
paddedImage =3D createPaddedImage(image, 1)
thresholdImg =3D paddedImage.point(lambda i, v=3D128: i > v and 255)
thresholdImg =3D ImageChops.invert(thresholdImg)
filteredImg =3D thresholdImg.filter(ImageFilter.FIND_EDGES)
thresholdImg =3D filteredImg.point(lambda i, v=3D128: i > v and 255)
arithImg =3D ImageChops.add(paddedImage, thresholdImg)
box =3D (1, 1, arithImg.size[0]-1, arithImg.size[1]-1)
outImage =3D arithImg.crop(box)
return outImage
def createPaddedImage(img, pad):
'''Create an padded image - since it is created with resize() the bor=
der =20
pixels will be same (almost) as the original edge pixels.'''
sizeX, sizeY =3D img.size
paddedImage =3D img.resize((sizeX+2*pad, sizeY+2*pad))
# paste original image into the new big image with an offset
paddedImage.paste(img, (pad, pad))
return paddedImage