Other Posts in Image Editing

  1. Perlin Noise
  2. Fault Formation
  3. Cellular Textures
  4. Resizing an Image in C#
  5. Box Blur and Gaussian Blur... Sort of...
  6. Thermal Erosion
  7. Using Mid Point Displacement to Create Cracks
  8. Fluvial Erosion
  9. Creating Marble Like Textures Procedurally
  10. Procedural Textures and Dilation
  11. Converting Image to Black and White in C#
  12. Getting an HTML Based Color Palette from an Image in C#
  13. Adding Noise/Jitter to an Image in C#
  14. Creating Pixelated Images in C#
  15. Edge detection in C#
  16. Using Sin to Get What You Want... In C#...
  17. Noise Reduction of an Image in C# using Median Filters
  18. Image Dilation in C#
  19. Sepia Tone in C#
  20. Kuwahara Filter in C#
  21. Matrix Convolution Filters in C#
  22. Symmetric Nearest Neighbor in C#
  23. Bump Map Creation Using C#
  24. Normal Map Creation Using C#
  25. Creating Negative Images using C#
  26. Red, Blue, and Green Filters in C#
  27. Converting an Image to ASCII Art in C#
  28. Adjusting Brightness of an Image in C#
  29. Adding Noise to an Image in C#
  30. Adjusting the Gamma of an Image Using C#
  31. Adjusting Contrast of an Image in C#
  32. Drawing a Box With Rounded Corners in C#
  33. Anding Two Images Together Using C#
  34. Motion Detection in C#
  35. Creating Thermometer Chart in C#
  36. Colorizing a Black and White Image in C#
  37. Extracting an Icon From a File
  38. Setting the Pixel Format and Image Format of an Image in .Net
  39. Using Unsafe Code for Faster Image Manipulation
  40. Sobel Edge Detection and Laplace Edge Detection in C#

Edge detection in C#


Edge detection is term used in image processing referring to algorithms that deal with changes in brightness/color. For instance if you wanted to be able to draw a box around a person, you'd need to find where the person began/ended and could (potentially) use edge detection to accomplish this (assuming the person was a different color from the background).  Generally speaking I wouldn't need this ability but I get bored every once in a while and code something for fun. That being said, there are quite a few algorithms that accomplish this but for my purposes, I created one of the easier ones (not the best, but definitely easy):

   1: /// <summary>
   2: /// Does basic edge detection on an image
   3: /// </summary>
   4: /// <param name="OriginalImage">Image to do edge detection on</param>
   5: /// <param name="Threshold">Decides what is considered an edge</param>
   6: /// <param name="EdgeColor">Color of the edge</param>
   7: /// <returns>A bitmap which has the edges drawn on it</returns>
   8: public static Bitmap EdgeDetection(Bitmap OriginalImage, float Threshold, Color EdgeColor)
   9: {
  10:     Bitmap NewBitmap = new Bitmap(OriginalImage, OriginalImage.Width, OriginalImage.Height);
  11:     BitmapData NewData = Image.LockImage(NewBitmap);
  12:     BitmapData OldData = Image.LockImage(OriginalImage);
  13:     int NewPixelSize = Image.GetPixelSize(NewData);
  14:     int OldPixelSize = Image.GetPixelSize(OldData);
  15:     for (int x = 0; x < NewBitmap.Width; ++x)
  16:     {
  17:         for (int y = 0; y < NewBitmap.Height; ++y)
  18:         {
  19:             Color CurrentColor = Image.GetPixel(OldData, x, y, OldPixelSize);
  20:             if (y < NewBitmap.Height - 1 && x < NewBitmap.Width - 1)
  21:             {
  22:                 Color TempColor = Image.GetPixel(OldData, x + 1, y + 1, OldPixelSize);
  23:                 if (Distance(CurrentColor.R, TempColor.R, CurrentColor.G, TempColor.G, CurrentColor.B, TempColor.B) > Threshold)
  24:                 {
  25:                     Image.SetPixel(NewData, x, y, EdgeColor, NewPixelSize);
  26:                 }
  27:             }
  28:             else if (y < NewBitmap.Height - 1)
  29:             {
  30:                 Color TempColor = Image.GetPixel(OldData, x, y + 1, OldPixelSize);
  31:                 if (Distance(CurrentColor.R, TempColor.R, CurrentColor.G, TempColor.G, CurrentColor.B, TempColor.B) > Threshold)
  32:                 {
  33:                     Image.SetPixel(NewData, x, y, EdgeColor, NewPixelSize);
  34:                 }
  35:             }
  36:             else if (x < NewBitmap.Width - 1)
  37:             {
  38:                 Color TempColor = Image.GetPixel(OldData, x + 1, y, OldPixelSize);
  39:                 if (Distance(CurrentColor.R, TempColor.R, CurrentColor.G, TempColor.G, CurrentColor.B, TempColor.B) > Threshold)
  40:                 {
  41:                     Image.SetPixel(NewData, x, y, EdgeColor, NewPixelSize);
  42:                 }
  43:             }
  44:         }
  45:     }
  46:     Image.UnlockImage(NewBitmap, NewData);
  47:     Image.UnlockImage(OriginalImage, OldData);
  48:     return NewBitmap;
  49: }
   1: private static double Distance(int R1, int R2, int G1, int G2, int B1, int B2)
   2: {
   3:     return System.Math.Sqrt(((R1 - R2) * (R1 - R2)) + ((G1 - G2) * (G1 - G2)) + ((B1 - B2) * (B1 - B2)));
   4: }

The code above simply looks at each pixel and compares it to its neighbors using a basic Euclidean distance function (Distance=SQRT((R1-R2)2+(G1-G2)2+(B1-B2)2)). If the "distance" between the colors is greater than the threshold, it sets the color to whatever is entered in as the edge color.  It's very basic and there are better methods out there but if all you need is something quick and dirty, this will do in a pinch. Also note that this function uses a couple of functions from my utility library, specifically to lock/unlock the image to speed things up. You can simply remove these parts and change the SetPixel/GetPixel parts to use the built in functions. Anyway, I hope this helps someone out, so try it out, leave feedback, and happy coding.


James Craig
September 15, 2010 10:14 AM

Actually it took about 2 hours, but the code for Sobel and Laplacian edge detection can be found here:http://www.gutgames.com/post/Sobel-Edge-Detection-and-Laplace-Edge-Detection-in-C.aspx

James Craig
September 15, 2010 8:42 AM

Do I have code for Sobel edge detection? Not at the moment. Give me a day or two and I'll post some though (as it's a decent project to undertake). The basics are pretty simple though. First convert the image to black and white, then basically you use two convolution filters:1 2 10 0 0-1 -2 -1and-1 0 1-2 0 2-1 0 1When you do that you'll have two images. You then take each pixel in each image and add them together. Copy that to your final image and you're done. And I do have code for convolution filters: http://www.gutgames.com/post/Matrix-Convolution-Filters-in-C.aspxand converting an image to black and white:http://www.gutgames.com/post/Converting-Image-to-Black-and-White-in-C.aspxSo it's just a matter of putting them together correctly.

September 13, 2010 12:31 PM

Cool code. Do you have any code regarding to the sobel edge detection??

James Craig
August 24, 2010 8:25 AM

Actually the sqrt isn't as slow as the setpixel and getpixel calls. But those can easily be replaced: http://www.gutgames.com/post/Using-Unsafe-Code-for-Faster-Image-Manipulation.aspx. That will give you the biggest speed boost. But past that, yes, the sqrt could easily be removed to speed things up.

August 24, 2010 5:25 AM

Hi.Very nice code, just what I was looking for.If you want to speed up it a lot, I recommend to remove the Sqrt functions and multiply by itself the threshold. Square roots is one of the slowest math opperations you can use on a computer, and multipliying by itself the threshold you will obtain the same result.Thanks for that beautiful routine :D

James Craig
July 26, 2010 8:30 AM

An entire program, no. But calling the function would look something like this:Bitmap MyImage=Bitmap.FromFile(FileLocation);Bitmap MyNewImage=EdgeDetection(MyImage,10.0f,Color.Red);

July 26, 2010 3:06 AM

Hi, thanks for the code. However, im new to this language, could you share the full program, since i dont know the structure to build the program.Thanks

April 22, 2010 4:11 AM

It was perfect. really good job.I have been looking for such a code but not complicatedand with no math equations.Accept my appreciation.