Sobel Horizontal Edge Detector Problem

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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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();	

}

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.

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.

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.

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 :slight_smile: