Click here to Skip to main content
6,630,289 members and growing! (21,349 online)
Email Password   helpLost your password?
Multimedia » GDI+ » General     Intermediate License: The Code Project Open License (CPOL)

Implementation of Laplacian of Gaussion Edge Detection Algorithm using C#

By Kunal Pawar

This code helps to implement LOG using C#
C# (C# 1.0, C# 2.0, C# 3.0), .NET, GDI+
Version:5 (See All)
Posted:18 Jun 2009
Views:5,030
Bookmarked:17 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
3 votes for this article.
Popularity: 2.19 Rating: 4.60 out of 5

1

2

3
1 vote, 33.3%
4
2 votes, 66.7%
5
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


Member
I am Software developer, worked on web technology and Windows. Willing to accept challengces and try to complete them.
Occupation: Software Developer (Senior)
Location: India India

Other popular GDI+ articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 2 of 2 (Total in Forum: 2) (Refresh)FirstPrevNext
Generalgood work Pinmembersalihovic0:45 22 Oct '09  
Newscolor image segmentation Pinmemberhieulinhanh18:42 19 Jul '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 18 Jun 2009
Editor: Deeksha Shenoy
Copyright 2009 by Kunal Pawar
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project