cdebuggingcs50sobel

Having trouble finding the error in my code for the CS50x problem set 4 "filter-more" for the function "Edges"


I initially wrote this code on paper, and as per my knowledge the could should work, but instead I am getting the wrong output.

Infile: https://imgur.com/oIffo7o
Outfile: https://imgur.com/rCNvW3L
Any kind of assistance is appreciated

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

    int Gy[3][3] = { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } };

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            int sumGx[3] = { 0, 0, 0 };
            int sumGy[3] = { 0, 0, 0 };

            for (int dy = -1; dy <= 1; dy++)
            {
                for (int dx = -1; dx <= 1; dx++)
                {
                    int ky = y + dy;
                    int kx = x + dx;

                    if ((ky > 0 && ky < height) && (kx > 0 && kx < width))
                    {
                        sumGx[0] += Gx[dy + 1][dx + 1] * image[ky][kx].rgbtRed;
                        sumGx[1] += Gx[dy + 1][dx + 1] * image[ky][kx].rgbtGreen;
                        sumGx[2] += Gx[dy + 1][dx + 1] * image[ky][kx].rgbtBlue;

                        sumGy[0] += Gy[dy + 1][dx + 1] * image[ky][kx].rgbtRed;
                        sumGy[1] += Gy[dy + 1][dx + 1] * image[ky][kx].rgbtGreen;
                        sumGy[2] += Gy[dy + 1][dx + 1] * image[ky][kx].rgbtBlue;
                    }
                }
            }

            int pixel_value[3] = { 0, 0, 0 };

            for (int i = 0; i < 3; i++)
            {
                if ((sumGx[i] != 0) && (sumGy[i] != 0))
                {
                    int squaredGx = sumGx[i] * sumGx[i];
                    int squaredGy = sumGy[i] * sumGy[i];
                    int edge = round(sqrt(squaredGx + squaredGy));

                    pixel_value[i] = edge > 255 ? 255 : edge;
                }
            }
            image[y][x].rgbtRed = pixel_value[0];
            image[y][x].rgbtGreen = pixel_value[1];
            image[y][x].rgbtBlue = pixel_value[2];
        }
    }

Here's the the code for RGBTRIPLE:

typedef struct
{
    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

Solution

  • So I found what I was doing wrong, I had to create a copy image of the original image. Then apply the Sobel operator on the copy image and assign the value to the image[y][x] pixel simultaneously. This way we can avoid skewing the results in the original image. The code I wrote before was changing each pixel's value and for the subsequent pixel, it would use the overwritten value hence producing different results for the overall image.

    Here's the addition made to the code:

    void edges(int height, int width, RGBTRIPLE image[height][width])
    {
        RGBTRIPLE original[height][width];
        memcpy(original, image, sizeof(RGBTRIPLE) * height * width);
    
        //* Existing code
        
                        if ((ky >= 0 && ky < height) && (kx >= 0 && kx < width))
                        {
                            sumGx[0] += Gx[dy + 1][dx + 1] * original[ky][kx].rgbtRed;
                            sumGx[1] += Gx[dy + 1][dx + 1] * original[ky][kx].rgbtGreen;
                            sumGx[2] += Gx[dy + 1][dx + 1] * original[ky][kx].rgbtBlue;
    
                            sumGy[0] += Gy[dy + 1][dx + 1] * original[ky][kx].rgbtRed;
                            sumGy[1] += Gy[dy + 1][dx + 1] * original[ky][kx].rgbtGreen;
                            sumGy[2] += Gy[dy + 1][dx + 1] * original[ky][kx].rgbtBlue;
                        } 
               // Rest of the code
               // Squaring and finding the value for each pixel using squaredGx and 
              squaredGy, and assigning the value to image[y][x]
    }
    

    This should do it. These additions solved the issue I was facing.