Morphological Operations

From the Binary Image Library homepage

The morphological operations are dilate, erode, open, and close. They are applied to a binary image with a structuring element.

Dilate

Pass the structuring element over the image. If any pixels set in the structuring element are set in the image, set the central pixel in the image.

Erode

Pass the structuring element over the image. If any pixels set in the sturcturing element are unset in the image, unset the central pixel in the image.

Open

Erode, then dilate with the same structuring element. Gets rid of small feaures.

Close

Dilate, then erode with the same structuring element. Gets rid of small holes.

What is the point of all this? By picking the right structuring element and applying an open followed by a close, or vice versa, you can get rid of image features you don't want. For example, if you want to keep disks but not lines, a morhological open operation with a disk-shaped structuring element will do the trick. Opening and closing is less destructive tha erode or dilate alone. Large features remain intact.

 

A morphological open operation with a disk of radius five pixels removes the lines whilst keeping the circles, admittedly distorting some of them a bit.

Some common structuring elements

Square Rectangle Line Diamond Octagon Disk
You can also use your own, user-defined elements.

Example

int testmorphologicalops()
{
	unsigned char se3x3[9] = { 1,1,1,1,1,1,1,1,1};
	unsigned char *secircle;
	int swidth, sheight;
	unsigned char *binary;
	int width, height;
	unsigned char opal[256 * 3];
	int transparent;
	unsigned char pal[2 * 3] = {
		0, 0, 0, 255, 255, 255
	};

	binary = loadgif("linesandcircles.gif", &width, &height, opal, &transparent);
	assert(binary);
	giftobinary(binary, width, height, opal, 256, transparent);

	swidth = 13;
	sheight = 13;
	secircle = malloc(swidth*sheight);
	memset(secircle, 0, swidth * sheight);
       /* hand drawing a circle to make the point you can use any se */
	fillcircle(secircle, swidth, sheight, 6, 6, 5);
	morphopen(binary, width, height, secircle, swidth, sheight);
	
	savegif("morphopen.gif", binary, width, height, pal, 2, -1, 0, 0);
}

Try it out