The following code i have written has the purpose of detecting the edges in a pixel using the sobel operator. However, it fails all of the tests given by check50 (tool offered by cs50). The output image is also the exact same as the input.
before you continue reading, visit the pset's link
- note: I'm supposed to form a 3x3 grid around the pixel I want to filter so that I can iterate over each value in the GX and GY values. I've used ints
hh
andww
to do this.
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
int sqrtRedd;
int sqrtGreenn;
int sqrtBluee;
//make copy of image
RGBTRIPLE copy[height][width];
for(int h = 0; h < height; h++)
{
for(int w = 0; w < width; w++)
{
copy[h][w] = image[h][w];
}
}
//loop through pixels
for(int h = 0; h < height; h++)
{
for(int w = 0; w < width; w++)
{
int GXred = 0;
int GYred = 0;
int GXgreen = 0;
int GYgreen = 0;
int GXblue = 0;
int GYblue = 0;
for(int hh = -1; hh <= 1; hh++)
{
for(int ww = -1; ww <= 1; ww++)
{
if( h + hh >= 0 && h + hh < height && w + ww >= 0 && w + ww < width)
{
//form 3x3 grid
GXred += ww * copy[2 - hh * hh][2 - ww * ww].rgbtRed;
GYred += hh * copy[2 - hh * hh][2 - ww * ww].rgbtRed;
GXgreen += ww * copy[2 - hh * hh][2 - ww * ww].rgbtGreen;
GYgreen += hh * copy[2 - hh * hh][2 - ww * ww].rgbtGreen;
GXblue += ww * copy[2 - hh * hh][2 - ww * ww].rgbtBlue;
GXblue += hh * copy[2 - hh * hh][2 - ww * ww].rgbtBlue;
}
}
}
int red = round(sqrt(GXred * GXred + GYred * GYred));
int green = round(sqrt(GXgreen * GXgreen + GYgreen * GXgreen));
int blue = round(sqrt(GXblue * GXblue + GYblue * GYblue));
if(red > 225)
{
red = 225;
}
else if(green > 225)
{
green = 225;
}
else if(blue > 225)
{
blue = 225
}
image[h][w].rgbtRed = red;
image[h][w].rgbtGreen = green;
image[h][w].rgbtBlue = blue;
}
}
return;
}
RGBTRIPLE:
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
These are the error messages given by check50:
:( edges correctly filters middle pixel
expected "210 150 60\n", not "143 105 30\n"
:( edges correctly filters pixel on edge
expected "213 228 255\n", not "164 144 79\n"
:( edges correctly filters pixel in corner
expected "76 117 255\n", not "58 77 64\n"
:( edges correctly filters 3x3 image
expected "76 117 255\n21...", not "58 77 64\n164 ..."
:( edges correctly filters 4x4 image
expected "76 117 255\n21...", not "58 77 64\n164 ..."
As you can see, the output values are way off and not even near what they should actually be. the problem is: I don't know if these errors are caused by a) my way of trying to find the GX and GY values from the kernels or b)by the way i'm applying the sobel operator.
I've tried finding GX and GY values in other ways (didn't work) such as:
if(hh == -1)
{
GYred += copy[h - 1][w + ww].rgbtRed * -1;
GYgreen += copy[h - 1][w + ww].rgbtGreen * -1;
GYblue += copy[h - 1][w + ww].rgbtBlue * -1;
}
else if( hh == 0)
{
GYred += copy[h][w + ww].rgbtRed * 0;
GYgreen += copy[h][w + ww].rgbtGreen * 0;
GYblue += copy[h][w + ww].rgbtBlue * 0;
}
else if(hh == 1)
{
GYred += copy[h + 1][w + ww].rgbtRed * 1;
GYgreen += copy[h + 1][w + ww].rgbtGreen * 1;
GYblue += copy[h + 1][w + ww].rgbtBlue * 2;
}
else if(hh == 2)
{
GYred += copy[h + 2][w + ww].rgbtRed * 2;
GYgreen += copy[h + 2][w + ww].rgbtGreen * 2;
GYblue += copy[h + 2][w + ww].rgbtBlue * 2;
}
//start setting GX values
if(ww == -2)
{
GXred += copy[h + hh][w - 2].rgbtRed * -2;
GXgreen += copy[h + hh][w - 2].rgbtGreen * -2;
GXblue += copy[h + hh][w - 2].rgbtBlue * -2;
}
else if(ww == -1)
{
GXred += copy[h + hh][w - 1].rgbtRed * -1;
GXgreen += copy[h + hh][w - 1].rgbtGreen * -1;
GXblue += copy[h + hh][w - 1].rgbtBlue * -1;
}
else if(ww == 0)
{
GXred += copy[h + hh][w].rgbtRed * 0;
GXgreen += copy[h + hh][w].rgbtGreen * 0;
GXblue += copy[h + hh][w].rgbtBlue * 0;
}
else if(ww == 1)
{
GXred += copy[h + hh][w + 1].rgbtRed * 1;
GXgreen += copy[h + hh][w + 1].rgbtGreen * 1;
GXblue += copy[h + hh][w + 1].rgbtBlue * 1;
}
I've been stuck on this pset for almost a week now and so at this point I don't know what else to try.
-1..1
but still check forhh==2
orww==-2
which does not make any sense. – GerhardhGXred += ww * copy[2 - hh * hh][2 - ww * ww].rgbtRed;
Please start writing down what values are going to be used as index. – Gerhardhelse if(blue > 225)
Why do you think, you don't need check for blue overflow if green overflowed? And where do you get limit225
? Should probably be255
. – Gerhardh