PDA

View Full Version : Sobel Horizontal Edge Detector Problem



Shakes
02-07-2011, 01:56 AM
Hello. I am having trouble getting my Sobel Horizontal Edge detector to work. I can get the smoothing filter to work (when the mask filter numbers are all 1). The only thing I changed for the horizontal filter is the mask filter numbers and I no longer divide mask totals by 9 since the filter sums up to 0. This method returns a very wrong looking picture. Do you see anything wrong with this Sobel horizontal edge detector algorithm? Thanks.

void sobelHorizontalEdgeDetector(pixel* Im, pixel* temp, int myIm_Width, int myIm_Height){
int x,y;
int maskTotalR = 0;
int maskTotalG = 0;
int maskTotalB = 0;

int lowerLeftMaskNum = -1; int leftMaskNum = 0; int upperLeftMaskNum = 1;
int bottomMaskNum = -2; int centerMaskNum = 0; int topMaskNum = 2;
int lowerRightMaskNum = -1; int rightMaskNum = 0; int upperRightMaskNum = 1;

for (x=1; x < myIm_Width-1; x++){
for (y=1; y < myIm_Height-1; y++){
for(int offsetX=-1; offsetX<2; offsetX++){
for(int offsetY=-1; offsetY<2; offsetY++){

if(offsetX==-1 &amp;&amp; offsetY==-1) //lower-left
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * lowerLeftMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * lowerLeftMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * lowerLeftMaskNum);
}
else if(offsetX==-1 &amp;&amp; offsetY==0) //left
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * leftMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * leftMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * leftMaskNum);
}
else if(offsetX==-1 &amp;&amp; offsetY==1) //upper-left
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * upperLeftMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * upperLeftMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * upperLeftMaskNum);
}
else if(offsetX==0 &amp;&amp; offsetY==-1) //bottom
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * bottomMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * bottomMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * bottomMaskNum);
}
else if(offsetX==0 &amp;&amp; offsetY==0) //center
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * centerMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * centerMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * centerMaskNum);
}
else if(offsetX==0 &amp;&amp; offsetY==1) //top
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * topMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * topMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * topMaskNum);
}
else if(offsetX==1 &amp;&amp; offsetY==-1) //bottom-right
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * lowerRightMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * lowerRightMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * lowerRightMaskNum);
}
else if(offsetX==1 &amp;&amp; offsetY==0) //right
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * rightMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * rightMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * rightMaskNum);
}
else if(offsetX==1 &amp;&amp; offsetY==1) //top-right
{
maskTotalR = maskTotalR + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].r * upperRightMaskNum);
maskTotalG = maskTotalG + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].g * upperRightMaskNum);
maskTotalB = maskTotalB + (Im[(x+offsetX)+(y+offsetY)*myIm_Width].b * upperRightMaskNum);
}
}
}
temp[x+y*myIm_Width].r = maskTotalR;
temp[x+y*myIm_Width].g = maskTotalG;
temp[x+y*myIm_Width].b = maskTotalB;

maskTotalR = 0;
maskTotalB = 0;
maskTotalG = 0;
}
}

global.data = tempBuffer.data;

glutPostRedisplay();
}

Rickard
02-07-2011, 02:29 AM
I havent check your code very much, in a bit of a hurry.
Many ppl who are doing soble filter for their first time forgets that after an image has be filter with a sobel kernel values dont necessarily span between 0-1 anymore. There is a big possibility that there are negativ numbers in the new image.

Take this example
Kernel:
[-1 0 1]
[-2 0 2]
[-1 0 1]

and at some point have underlaying pixels like this:

1 0 0
1 0 0
1 0 0

will result in a pixel with the value -4.

So what you need to do in that case is to normalize the values between 0-1.

Shakes
02-07-2011, 05:28 PM
Hi Rickard, thanks for the reply. I normalized the values between 0 and 255 by using this: z= a+b-a*b/256. Although the values are normalized now, the mask totals still go over the 255 range since I am adding all of the totals together to make maskTotalR, maskTotalG, and maskTotalB. I tried going maskTotalR%256, etc.. to get the totals back into the 0-255 range but then I get the original wrong looking image that I had. Any suggestions? Thanks.

Rickard
02-08-2011, 03:27 AM
When you normalize your values they should be in the 0-255 range. Maybe your formula isnt entirely correct.
I would have saved the min value and maxvlue for each chanel i temp. Then after the loop I would loop through each channel and take the current value and :

temp[current].r = 255 * (temp[current].r - minR) / (maxR - minR)

I've just did it on paper, it should work.

Shakes
02-08-2011, 08:06 PM
Hi. The normalization of the values worked but after I added up all the values I didn't make sure the bounds of the pixel value (x) were 0<=x<=255. I think that was my problem. Thanks for the help :)