Click here to Skip to main content
Licence CPOL
First Posted 18 Jun 2009
Views 21,969
Downloads 1,521
Bookmarked 27 times

Implementation of Laplacian of Gaussion Edge Detection Algorithm using C#

By Kunal Pawar | 18 Jun 2009
This code helps to implement LOG using C#

1

2

3
1 vote, 33.3%
4
2 votes, 66.7%
5
4.60/5 - 3 votes
μ 4.60, σa 1.01 [?]
Edge_Detection_Code

Introduction 

The Laplacian of Gaussian filter is a convolution filter that is used to detect edges. This filter first applies a Gaussian blur, then applies the Laplacian filter and finally checks for zero crossings (i.e. when the resulting value goes from negative to positive or vice versa). The end result of this filter is to highlight edges. The operator normally takes a single graylevel image as input and produces another binary image as output. Pointers are used in the code so it is much faster.

Edge detection is a problem of fundamental importance in image analysis. In typical images, edges characterize object boundaries and are therefore useful for segmentation, registration, and identification of objects in a scene. For edge detection, there are various algorithms used like Sobel,Roberts Filter, LoG, etc.
The following links help to explain about LoG:

Using the Code

In this code, first we find the mean of image and deviation of image. Using deviation of image, we will decide threshold of image allowed to display. GetPixel and SetPixel functions have several drawbacks so we use Pointer. We access and modify a pixel value using Pointer. The next example utilizes the “unsafe” block in C#. Inside unsafe blocks, we have access to pointers from C#. The conclusion is that pointers in unsafe blocks are faster than GetPixel and SetPixel functions.

// Open Bitmap for Source image & destination.
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, 
	bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

BitmapData srcData = SrcImage.LockBits(new Rectangle(0, 0, SrcImage.Width, 
	SrcImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

Lock bits for source image in read only format and get BitmapData object. Lock bits for destination image in read and write format and set BitmapData.

// Find mean of Image.
for (int colm = 0; colm < srcData.Height - size; colm++)
{
	byte* ptr = (byte*)srcData.Scan0 + (colm * srcData.Stride);
	
	for (int row = 0; row < srcData.Width - size; row++)
	{
		nTemp = 0.0;
		
		for (k = 0; k < size; k++)
		{
			for (l = 0; l < size; l++)
			{
				byte* tempPtr = (byte*)srcData.Scan0 + 
					((colm + l) * srcData.Stride);
				c = (tempPtr[((row + k) * offset)] + 
					tempPtr[((row + k) * offset) + 1] + 
					tempPtr[((row + k) * offset) + 2]) / 3;

				nTemp += (double)c * MASK[k, l];
			}
		}
		
		sum += nTemp;
		n++;
	}
}
mean = ((double)sum / n);

// Find deviation of Image.
for (int i = 0; i < srcData.Height - size; i++)
{
	byte* ptr = (byte*)srcData.Scan0 + (i * srcData.Stride);
	
	for (int j = 0; j < srcData.Width - size; j++)
	{
		nTemp = 0.0;
		
		for (k = 0; k < size; k++)
		{
			for (l = 0; l < size; l++)
			{
				byte* tempPtr = (byte*)srcData.Scan0 + 
						((i + l) * srcData.Stride);
				c = (tempPtr[((j + k) * offset)] + 
					tempPtr[((j + k) * offset) + 1] + 
					tempPtr[((j + k) * offset) + 2]) / 3;

				nTemp += (double)c * MASK[k, l];
			
			}
		}
		
		s = (mean - nTemp);
		d += (s * s);
	}
}

d = d / (n - 1);
d = Math.Sqrt(d);
d = d * 2;

This code is used to calculate the mean of image and deviation of image which helps to decide threshold range of image.

for (int colm = mdl; colm < srcData.Height - mdl; colm++)
{
	byte* ptr = (byte*)srcData.Scan0 + (colm * srcData.Stride);
	byte* bitmapPtr = (byte*)bitmapData.Scan0 + (colm * bitmapData.Stride);

	for (int row = mdl; row < srcData.Width - mdl; row++)
	{
		nTemp = 0.0;

		min = double.MaxValue;
		max = double.MinValue;

		// Get neighbour Pixels.
		for (k = (mdl * -1); k < mdl; k++)
		{
			for (l = (mdl * -1); l < mdl; l++)
			{
				byte* tempPtr = (byte*)srcData.Scan0 + 
						((colm + l) * srcData.Stride);
				c = (tempPtr[((row + k) * offset)] + 
					tempPtr[((row + k) * offset) + 1] + 
					tempPtr[((row + k) * offset) + 2]) / 3;

				nTemp += (double)c * MASK[mdl + k, mdl + l];
			}
		}

		if (nTemp > d)
		{
			bitmapPtr[row * offset] = bitmapPtr[row * offset + 1] = 
						bitmapPtr[row * offset + 2] = 255;
		}
		else
		{
			bitmapPtr[row * offset] = bitmapPtr[row * offset + 1] = 
						bitmapPtr[row * offset + 2] = 0;
		}
	}
}

This code is used to mark identified part as white and the remaining with black pixel value. Using outer nested loops, we visit each pixel and find its neighbouring pixel using the inner FOR loop. Multiply pixel array with Mask array and add into threshold value(nTemp). After visiting all neighbour pixels, compare threshold value(nTemp) with deviation (d), put WHITE pixel if threshold value(nTemp) is greater than deviation(d) otherwise BLACK pixel.

bitmap.UnlockBits(bitmapData);
SrcImage.UnlockBits(srcData);

Unlock the locked bits so that it frees bitmap object, and we can modify bitmap object in future.

Points of Interest 

Finding image deviation and Threshold using Mathematical calculation is best.

History

  • 18th June, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Kunal Pawar

Software Developer (Senior)

India India

Member
I am Software developer, working on web and Windows technology. Willing to accept challengces and try to complete them.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalgood work Pinmembersalihovic0:45 22 Oct '09  
Newscolor image segmentation Pinmemberhieulinhanh18:42 19 Jul '09  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120210.1 | Last Updated 18 Jun 2009
Article Copyright 2009 by Kunal Pawar
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid