Function produces incorrect blue channel value trying to apply Sobel Operator for edge detection

27 views Asked by At

So I have been trying to write a function that implements the Sobel Operator on a bitmap image as part of an assignment for CS50.

The thing I've been struggling with last couple of hours is identifying what is wrong with my code in implementing this function as it correctly produces the values for the Red and Green Channel but does so incorrectly for the Blue Channel.

I am attaching the image of the error message I get from CS50 when i run the check50 cs50/problems/2024/x/filter/more prompt at the command line which checks the code I've written against test cases written by CS50.

Failed Test Cases

I am attaching a link to the assignment below. You may have to scroll down a bit to get to the 'edge' section of the assignment where the finer details of the assignment are explained in relation to the edge detection implementation of the function.

As you might have already guessed by now, I am a total newbie to programming so really any help will be greatly appreciated! Also, please excuse me If I have not taken any steps people normally would in making the code more readable.

Link to the assignment: https://cs50.harvard.edu/x/2024/psets/4/filter/more/

I have pasted the function I've written so far. For some reason, it produces the correct values for the Red and Green Channel but does so incorrectly for the Blue channel.

void edges(int height, int width, RGBTRIPLE image[height][width])
{
    int Gx_Matrix[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
    int Gy_Matrix[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};
    RGBTRIPLE copy[height][width];

    // Create a copy of the originial image //
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            copy[i][j] = image[i][j];
        }
    }

    // Loop over each pixel //

    // Calculate the weighted sum of each colour channel //

    // Combine the Gx and Gy weight sum to attain a single value for each channel //

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            float Gx_SumRed = 0;
            float Gy_SumRed = 0;
            float Gx_SumGreen = 0;
            float Gy_SumGreen = 0;
            float Gx_SumBlue = 0;
            float Gy_SumBlue = 0;

            for (int di = -1; di <= 1; di++)
            {
                for (int dj = -1; dj <= 1; dj++)
                {
                    int ni = i + di;
                    int nj = j + dj;

                    if((ni >= 0) && (ni < height) && (nj >= 0) && (nj < width))
                    {
                        Gx_SumRed += Gx_Matrix[di + 1][dj + 1] * (copy[ni][nj].rgbtRed);
                        Gx_SumGreen += Gx_Matrix[di + 1][dj + 1] * (copy[ni][nj].rgbtGreen);
                        Gx_SumBlue += Gx_Matrix[di + 1][dj + 1] * (copy[ni][nj].rgbtBlue);

                        Gy_SumRed += Gy_Matrix[di + 1][dj + 1] * (copy[ni][nj].rgbtRed);
                        Gy_SumGreen += Gy_Matrix[di + 1][dj + 1] * (copy[ni][nj].rgbtGreen);
                        Gy_SumBlue += Gy_Matrix[di + 1][dj + 1] * (copy[ni][nj].rgbtBlue);
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            image[i][j].rgbtRed = round(sqrt((Gx_SumRed * Gx_SumRed) + (Gy_SumRed * Gy_SumRed)));
            image[i][j].rgbtGreen = round(sqrt((Gx_SumGreen * Gx_SumGreen) + (Gy_SumGreen * Gy_SumGreen)));
            image[i][j].rgbtBlue = round(sqrt((Gx_SumBlue * Gx_SumBlue) + (Gy_SumBlue * Gy_SumBlue)));

            if (image[i][j].rgbtRed > 255)
            {
                image[i][j].rgbtRed = 255;
            }

            if (image[i][j].rgbtGreen > 255)
            {
                image[i][j].rgbtGreen = 255;
            }

            if (image[i][j].rgbtBlue > 255)
            {
                image[i][j].rgbtBlue = 255;
            }
        }
    }
    return;
}

I also understand that I need to produce a minimally reproducible piece of code. Since CS50 has separated this function from the main implementation of the rest of the program as helper functions, you may need to download the distribution code for the remaining program. You can do so by running the following prompt at the command line:

wget https://cdn.cs50.net/2023/fall/psets/4/filter-more.zip

You can find the function itself in a file called helpers.c.

I don't know if this is particularly insightful, but in the test cases written by CS50, the correct blue channel values is 255. I am not sure if the code I've written only produces the wrong value when the correct value is 255 or if it produces the wrong value for other cases as well when the correct Blue channel value isn't 255.

I did check my code to prevent value overflow from occurring whenever the returning value exceeds 255 to cap it at 255. I don't see any errors in the implementation for that as well.

0

There are 0 answers