I have written the below code for CS50 Pset4 for the edge (Sobel filter)
Here is a link for CS50 Pset4 problem description (Edges part only): https://cs50.harvard.edu/x/2020/psets/4/filter/more/
My code that I have written presents a sobel filter image, but my problem is only with border pixel.
Here is my code:
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE imgCopy[height][width];
float gxRed;
float gxGreen;
float gxBlue;
float gyRed;
float gyGreen;
float gyBlue;
float gRed;
float gGreen;
float gBlue;
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
imgCopy[h][w].rgbtRed = image[h][w].rgbtRed;
imgCopy[h][w].rgbtGreen = image[h][w].rgbtGreen;
imgCopy[h][w].rgbtBlue = image[h][w].rgbtBlue;
}
}
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
// Top left Corner
if (h == 0 && w == 0)
{
// For Gx and Gy values imagine a 3x3 matrix at the corner and any pixel outside the corner is considered to be equal zero
//(The corner pixels does not equal 0 you treat the corner pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = 2 * imgCopy[h][w + 1].rgbtRed + imgCopy[h + 1][w + 1].rgbtRed;
gxGreen = 2 * imgCopy[h][w + 1].rgbtGreen + imgCopy[h + 1][w + 1].rgbtGreen;
gxBlue = 2 * imgCopy[h][w + 1].rgbtBlue + imgCopy[h + 1][w + 1].rgbtBlue;
gyRed = 2 * imgCopy[h + 1][w].rgbtRed + imgCopy[h + 1][w + 1].rgbtRed ;
gyGreen = 2 * imgCopy[h + 1][w].rgbtGreen + imgCopy[h + 1][w + 1].rgbtGreen;
gyBlue = 2 * imgCopy[h + 1][w].rgbtBlue + imgCopy[h + 1][w + 1].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Top-right corner
else if ( h == 0 && w == width - 1 )
{
// For Gx and Gy values imagine a 3x3 matrix at the corner and any pixel outside the corner is considered to be equal zero
//(The corner pixels does not equal 0 you treat the corner pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = -2 * imgCopy[h][w - 1].rgbtRed + -1 * imgCopy[h + 1][w - 1].rgbtRed;
gxGreen = -2 * imgCopy[h][w - 1].rgbtGreen + -1 * imgCopy[h + 1][w - 1].rgbtGreen;
gxBlue = -2 * imgCopy[h][w - 1].rgbtBlue + -1 * imgCopy[h + 1][w - 1].rgbtBlue;
gyRed = 2 * imgCopy[h + 1][w].rgbtRed + imgCopy[h + 1][w - 1].rgbtRed;
gyGreen = 2 * imgCopy[h + 1][w].rgbtGreen + imgCopy[h + 1][w - 1].rgbtGreen;
gyBlue = 2 * imgCopy[h + 1][w].rgbtBlue + imgCopy[h + 1][w - 1].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Bottom left corner
else if (h == height - 1 && w == 0 )
{
// For Gx and Gy values imagine a 3x3 matrix at the corner and any pixel outside the corner is considered to be equal zero
//(The corner pixels does not equal 0 you treat the corner pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = 1 * imgCopy[h - 1][w + 1].rgbtRed + 2 * imgCopy[h][w + 1].rgbtRed;
gxGreen = 1 * imgCopy[h - 1][w + 1].rgbtGreen + 2 * imgCopy[h][w + 1].rgbtGreen;
gxBlue = 1 * imgCopy[h - 1][w + 1].rgbtBlue + 2 * imgCopy[h][w + 1].rgbtBlue;
gyRed = -1 * imgCopy[h - 1][w + 1].rgbtRed + -2 * imgCopy[h - 1][w].rgbtRed;
gyGreen = -1 * imgCopy[h - 1][w + 1].rgbtGreen + -2 * imgCopy[h - 1][w].rgbtGreen;
gyBlue = -1 * imgCopy[h - 1][w + 1].rgbtBlue + -2 * imgCopy[h - 1][w].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Bottom-right corner
else if ( h == height - 1 && w == width - 1 )
{
// For Gx and Gy values imagine a 3x3 matrix at the corner and any pixel outside the corner is considered to be equal zero
//(The corner pixels does not equal 0 you treat the corner pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = -1 * imgCopy[h - 1][w - 1].rgbtRed + -2 * imgCopy[h][w - 1].rgbtRed;
gxGreen = -1 * imgCopy[h - 1][w - 1].rgbtGreen + -2 * imgCopy[h][w - 1].rgbtGreen;
gxBlue = -1 * imgCopy[h - 1][w - 1].rgbtBlue + -2 * imgCopy[h][w - 1].rgbtBlue;
gyRed = -1 * imgCopy[h - 1][w - 1].rgbtRed + -2 * imgCopy[h - 1][w].rgbtRed;
gyGreen = -1 * imgCopy[h - 1][w - 1].rgbtGreen + -2 * imgCopy[h - 1][w].rgbtGreen;
gyBlue = -1 * imgCopy[h - 1][w - 1].rgbtBlue + -2 * imgCopy[h - 1][w].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Top border pixels
else if ( h == 0 && (w > 0 && w < width - 1) )
{
// For Gx and Gy values imagine a 3x3 matrix at the border and any pixel outside the border is considered to be equal zero
//(The border pixels does not equal 0 you treat the border pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = -1 * imgCopy[h][w - 1].rgbtRed + 1 * imgCopy[h][w + 1].rgbtRed;
gxGreen = -1 * imgCopy[h][w - 1].rgbtGreen + 1 * imgCopy[h][w + 1].rgbtGreen;
gxBlue = -1 * imgCopy[h][w - 1].rgbtBlue + 1 * imgCopy[h][w + 1].rgbtBlue;
gyRed = 1 * imgCopy[h][w - 1].rgbtRed + 2 * imgCopy[h][w].rgbtRed + 1 * imgCopy[h][w + 1].rgbtRed;
gyGreen = 1 * imgCopy[h][w - 1].rgbtGreen + 2 * imgCopy[h][w].rgbtGreen + 1 * imgCopy[h][w + 1].rgbtGreen;
gyBlue = 1 * imgCopy[h][w - 1].rgbtBlue + 2 * imgCopy[h][w].rgbtBlue + 1 * imgCopy[h][w + 1].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Bottom border pixels
else if ( h == height - 1 && (w > 0 && w < width - 1) )
{
// For Gx and Gy values imagine a 3x3 matrix at the border and any pixel outside the border is considered to be equal zero
//(The border pixels does not equal 0 you treat the border pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = -1 * imgCopy[h][w - 1].rgbtRed + 1 * imgCopy[h][w + 1].rgbtRed;
gxGreen = -1 * imgCopy[h][w - 1].rgbtGreen + 1 * imgCopy[h][w + 1].rgbtGreen;
gxBlue = -1 * imgCopy[h][w - 1].rgbtBlue + 1 * imgCopy[h][w + 1].rgbtBlue;
gyRed = -1 * imgCopy[h][w - 1].rgbtRed + -2 * imgCopy[h][w].rgbtRed + -1 * imgCopy[h][w + 1].rgbtRed;
gyGreen = -1 * imgCopy[h][w - 1].rgbtGreen + -2 * imgCopy[h][w].rgbtGreen + -1 * imgCopy[h][w + 1].rgbtGreen;
gyBlue = -1 * imgCopy[h][w - 1].rgbtBlue + -2 * imgCopy[h][w].rgbtBlue + -1 * imgCopy[h][w + 1].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Left-side border pixels
else if ( (h > 0 && h < height - 1) && w == 0 )
{
// For Gx and Gy values imagine a 3x3 matrix at the border and any pixel outside the border is considered to be equal zero
//(The border pixels does not equal 0 you treat the border pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = 1 * imgCopy[h - 1][w].rgbtRed + 2 * imgCopy[h][w].rgbtRed + 1 * imgCopy[h + 1][w].rgbtRed;
gxGreen = 1 * imgCopy[h - 1][w].rgbtGreen + 2 * imgCopy[h][w].rgbtGreen + 1 * imgCopy[h + 1][w].rgbtGreen;
gxBlue = 1 * imgCopy[h - 1][w].rgbtBlue + 2 * imgCopy[h][w].rgbtBlue + 1 * imgCopy[h + 1][w].rgbtBlue;
gyRed = -1 * imgCopy[h - 1][w].rgbtRed + 1 * imgCopy[h + 1][w].rgbtRed;
gyGreen = -1 * imgCopy[h - 1][w].rgbtGreen + 1 * imgCopy[h + 1][w].rgbtGreen;
gyBlue = -1 * imgCopy[h - 1][w].rgbtBlue + 1 * imgCopy[h + 1][w].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Right-side border pixels
else if ( (h > 0 && h < height - 1) && w == width - 1 )
{
// For Gx and Gy values imagine a 3x3 matrix at the border and any pixel outside the border is considered to be equal zero
//(The border pixels does not equal 0 you treat the border pixel as a 3x3 matrix same as the middle pixels and get the Gx and Gy values for them)
gxRed = -1 * imgCopy[h - 1][w].rgbtRed + -2 * imgCopy[h][w].rgbtRed + -1 * imgCopy[h + 1][w].rgbtRed;
gxGreen = -1 * imgCopy[h - 1][w].rgbtGreen + -2 * imgCopy[h][w].rgbtGreen + -1 * imgCopy[h + 1][w].rgbtGreen;
gxBlue = -1 * imgCopy[h - 1][w].rgbtBlue + -2 * imgCopy[h][w].rgbtBlue + -1 * imgCopy[h + 1][w].rgbtBlue;
gyRed = -1 * imgCopy[h - 1][w].rgbtRed + 1 * imgCopy[h + 1][w].rgbtRed;
gyGreen = -1 * imgCopy[h - 1][w].rgbtGreen + 1 * imgCopy[h + 1][w].rgbtGreen;
gyBlue = -1 * imgCopy[h - 1][w].rgbtBlue + 1 * imgCopy[h + 1][w].rgbtBlue;
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
// Middle 3x3 pixels
else
{
gxRed = (float)((-1 * imgCopy[h - 1][w - 1].rgbtRed) + (0 * imgCopy[h - 1][w].rgbtRed) + (1 * imgCopy[h - 1][w + 1].rgbtRed) +
(-2 * imgCopy[h][w - 1].rgbtRed) + (0 * imgCopy[h][w].rgbtRed) + (2 * imgCopy[h][w + 1].rgbtRed) +
(-1 * imgCopy[h + 1][w - 1].rgbtRed) + (0 * imgCopy[h + 1][w].rgbtRed) + (1 * imgCopy[h + 1][w + 1].rgbtRed));
gxGreen = (float)((-1 * imgCopy[h - 1][w - 1].rgbtGreen) + (0 * imgCopy[h - 1][w].rgbtGreen) + (1 * imgCopy[h - 1][w + 1].rgbtGreen) +
(-2 * imgCopy[h][w - 1].rgbtGreen) + (0 * imgCopy[h][w].rgbtGreen) + (2 * imgCopy[h][w + 1].rgbtGreen) +
(-1 * imgCopy[h + 1][w - 1].rgbtGreen) + (0 * imgCopy[h + 1][w].rgbtGreen) + (1 * imgCopy[h + 1][w + 1].rgbtGreen));
gxBlue = (float)((-1 * imgCopy[h - 1][w - 1].rgbtBlue) + (0 * imgCopy[h - 1][w].rgbtBlue) + (1 * imgCopy[h - 1][w + 1].rgbtBlue) +
(-2 * imgCopy[h][w - 1].rgbtBlue) + (0 * imgCopy[h][w].rgbtBlue) + (2 * imgCopy[h][w + 1].rgbtBlue) +
(-1 * imgCopy[h + 1][w - 1].rgbtBlue) + (0 * imgCopy[h + 1][w].rgbtBlue) + (1 * imgCopy[h + 1][w + 1].rgbtBlue));
gyRed = (float)((-1 * imgCopy[h - 1][w - 1].rgbtRed) + (-2 * imgCopy[h - 1][w].rgbtRed) + (-1 * imgCopy[h - 1][w + 1].rgbtRed) +
(0 * imgCopy[h][w - 1].rgbtRed) + (0 * imgCopy[h][w].rgbtRed) + (0 * imgCopy[h][w + 1].rgbtRed) +
(1 * imgCopy[h + 1][w - 1].rgbtRed) + (2 * imgCopy[h + 1][w].rgbtRed) + (1 * imgCopy[h + 1][w + 1].rgbtRed));
gyGreen = (float)((-1 * imgCopy[h - 1][w - 1].rgbtGreen) + (-2 * imgCopy[h - 1][w].rgbtGreen) + (-1 * imgCopy[h - 1][w + 1].rgbtGreen) +
(0 * imgCopy[h][w - 1].rgbtGreen) + (0 * imgCopy[h][w].rgbtGreen) + (0 * imgCopy[h][w + 1].rgbtGreen) +
(1 * imgCopy[h + 1][w - 1].rgbtGreen) + (2 * imgCopy[h + 1][w].rgbtGreen) + (1 * imgCopy[h + 1][w + 1].rgbtGreen));
gyBlue = (float)((-1 * imgCopy[h - 1][w - 1].rgbtBlue) + (-2 * imgCopy[h - 1][w].rgbtBlue) + (-1 * imgCopy[h - 1][w + 1].rgbtBlue) +
(0 * imgCopy[h][w - 1].rgbtBlue) + (0 * imgCopy[h][w].rgbtBlue) + (0 * imgCopy[h][w + 1].rgbtBlue) +
(1 * imgCopy[h + 1][w - 1].rgbtBlue) + (2 * imgCopy[h + 1][w].rgbtBlue) + (1 * imgCopy[h + 1][w + 1].rgbtBlue));
gRed = sqrt((gxRed * gxRed) + (gyRed * gyRed));
gGreen = sqrt((gxGreen * gxGreen) + (gyGreen * gyGreen));
gBlue = sqrt((gxBlue * gxBlue) + (gyBlue * gyBlue));
gRed = round(gRed);
gGreen = round(gGreen);
gBlue = round(gBlue);
if(gRed > 255)
{
gRed = 255;
}
if(gGreen > 255)
{
gGreen = 255;
}
if(gBlue > 255)
{
gBlue = 255;
}
image[h][w].rgbtRed = gRed;
image[h][w].rgbtGreen = gGreen;
image[h][w].rgbtBlue = gBlue;
}
}
}
return;
}
Those are the error messages that i get when i run (check50) to check my code:
:) edges correctly filters middle pixel (this part is correct)
:( edges correctly filters pixel on edge expected "213 228 255\n", not "57 103 174\n"
:) edges correctly filters pixel in corner. (this part is correct)
:( edges correctly filters 3x3 image expected "76 117 255\n21...", not "76 117 255\n57..."
:( edges correctly filters 4x4 image expected "76 117 255\n21...", not "76 117 255\n57..."