Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

New Method of Edge Detection

0.00/5 (No votes)
17 Sep 2010 1  
This is a flexible and scalable way of edge detection.

Introduction

This is a new method of edge detection and it is flexible and scalable.

Background

I had the need for a flexible and scalable edge detection. So, I could use sobel, prewitt or canny. In sobel & prewitt, it is hard to change the edge thickness. But my edge detection has only a threshold value, if you change it, output will be different.

Why is it New

Sobel & Prewitt edge detection perform a 3X3 matrix multiplication operation upon all the pixels on the image and their complexity is width * height * 3 * 3. But my method of edge detection finds the difference among the neighbouring pixels and if any difference is greater or equal than the threshold value (normally 90), then consider them as an edge and its complexity is width * height. If we increase the threshold value, then edge will decrease, and if threshold value decreases, then the edge will increase. So, there is an inverse relation among the edge and the threshold value. But in sobel & prewitt, we cannot increase or decrease the edges. For different image, sometime, we need to increase or decrease the edges.

Concept

The color difference of two neighbouring pixels in opposite direction of an edge is large. Without edge, color difference of neighbour pixels is small.

How Does it Work?

Edge_1.PNG

Each pixel has 8 neighbours. If pixel co-ordinate is x & y. Then its neighbouring pixels are (x+1,y+1), (x,y+1), (x+1,y), (x-1,y-1), (x,y-1), (x-1,y), (x-1,y+1) & (x+1,y-1). The color difference of two pixels means RGB difference among the two pixels. If two pixels are (x,y) & (a,b), then the color difference will be:

int total = Math.Abs(b.GetPixel(a, b).B - b.GetPixel(x, y).B) + 
		Math.Abs(b.GetPixel(a, b).R - b.GetPixel(x, y).R) + 
		Math.Abs(b.GetPixel(a, b).G - b.GetPixel(x, y).G);

In my method of edge detection, 1st takes a bitmap whose height & width is similar to the original image and the color of all its pixels is white.

int n, m;
n = b.Height;
m = b.Width;
int total = 0;
Bitmap B1 = new Bitmap(m, n);
for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
    {
        B1.SetPixel(i, j, Color.White);
    }

Then for each pixel of an image, it determines the color difference, of its neighbour's pixels. If any neighbour's color difference is greater or equal than the threshold value, then it is an edge & gives the pixel value Black. Normally threshold value is 90. But if we are increasing the threshold value, then the edge will decrease and if the threshold value decreases then the edge will increase.

for (int i = 1; i < m - 1; i++)
for (int j = 1; j < n - 1; j++)
{
    total = Math.Abs(b.GetPixel(i + 1, j + 1).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i + 1, j + 1).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i + 1, j + 1).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
    
    total = Math.Abs(b.GetPixel(i, j + 1).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i, j + 1).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i, j + 1).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
    
    total = Math.Abs(b.GetPixel(i + 1, j).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i + 1, j).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i + 1, j).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
    
    total = Math.Abs(b.GetPixel(i - 1, j - 1).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i - 1, j - 1).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i - 1, j - 1).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
    
    total = Math.Abs(b.GetPixel(i, j - 1).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i, j - 1).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i, j - 1).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
    
    total = Math.Abs(b.GetPixel(i - 1, j).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i - 1, j).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i - 1, j).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
    
    total = Math.Abs(b.GetPixel(i - 1, j + 1).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i - 1, j + 1).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i - 1, j + 1).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
    
    total = Math.Abs(b.GetPixel(i + 1, j - 1).B - b.GetPixel(i, j).B) + 
    	Math.Abs(b.GetPixel(i + 1, j - 1).R - b.GetPixel(i, j).R) + 
    	Math.Abs(b.GetPixel(i + 1, j - 1).G - b.GetPixel(i, j).G);
    if (total > _proposedThresoldValue)
    { B1.SetPixel(i, j, Color.Black); continue; }
}

Edge_2.PNG

We can compare my method of edge detection to sobel or prewitt edge detection. For comparing this, we have to select sobel or prewitt check box and proposed check box. Black pixel indicates that this pixel is common for proposed and sobel/prewitt. Red pixel indicates that this pixel is only for sobel/prewitt. And blue pixel indicates that this pixel is only for proposed.

if (checkBox_sobel.Checked && checkBox_pro.Checked)
{
    Bitmap b1 = (Bitmap)pictureBox2.Image;
    Bitmap b2 = (Bitmap)pictureBox4.Image;
    Bitmap map = new Bitmap(pictureBox2.Image.Width, pictureBox2.Image.Height);
    
    for (int i = 1; i < b1.Width - 1; i++)
        for (int j = 1; j < b1.Height - 1; j++)
        {
            if (b1.GetPixel(i, j).R == 0 && b2.GetPixel(i, j).R == 0)
                map.SetPixel(i, j, Color.Black);
            else if (b1.GetPixel(i, j).R == 0)
                map.SetPixel(i, j, Color.Red);
            else if (b2.GetPixel(i, j).R == 0)
                map.SetPixel(i, j, Color.Blue);
        }
        
    pictureBox5.Image = map;
}
else if (checkBox_prewitt.Checked && checkBox_pro.Checked)
{
    Bitmap b1 = (Bitmap)pictureBox3.Image;
    Bitmap b2 = (Bitmap)pictureBox4.Image;
    Bitmap map = new Bitmap(pictureBox3.Image.Width, pictureBox3.Image.Height);
    
    for (int i = 1; i < b1.Width - 1; i++)
        for (int j = 1; j < b1.Height - 1; j++)
        {
            if (b1.GetPixel(i, j).R == 0 && b2.GetPixel(i, j).R == 0)
                map.SetPixel(i, j, Color.Black);
            else if (b1.GetPixel(i, j).R == 0)
                map.SetPixel(i, j, Color.Red);
            else if (b2.GetPixel(i, j).R == 0)
                map.SetPixel(i, j, Color.Blue);
        }
        
    pictureBox5.Image = map;
}

If we decrease the threshold value, than edge will be thicker and if we increase the threshold value, then edge will be wider.

History

  • 10th September, 2010: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here