CS50: Filter Edge Returns Mostly White Image

Issue

I have been stuck on CS50 Filter – Edges for a few days now, having a hard time determining what’s wrong with my code. This code returns an almost all white images (which indicates to me final values are too large for each of the pixels). Any help would be greatly appreciated!

I’ve checked with my friend’s code as well and I don’t see any obvious logic flaws with the code, the image is mostly white and there’s definitely no edges detected in the image.

void edges(int height, int width, RGBTRIPLE image[height][width])
{
    //Create Gx and Gy Matrixes
    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}};
    //create copy of image
    RGBTRIPLE copy[height][width];
    for(int row=0; row<height;row++)
    {
        for(int col=0; col<width; col++)
        {

            copy[row][col].rgbtBlue=image[row][col].rgbtBlue;
            copy[row][col].rgbtRed=image[row][col].rgbtRed;
            copy[row][col].rgbtGreen=image[row][col].rgbtGreen;
        }
    }
    //create loop for edge detection
    int red; int blue; int green;
    double Gxsum[3]; double Gysum[3]; double finalval[3];
    int icount; int jcount;

    for(int row=0; row<height; row++)//inside image loop
    {

        for(int col=0; col<width; col++)
        {
            Gxsum[0]=0.0; Gxsum[1]=0.0; Gxsum[2]=0.0;
            Gysum[0]=0.0; Gysum[1]=0.0; Gysum[2]=0.0;
            icount=0; jcount=0;
            for(int i=row-1; i<=row+1; i++)//inside 3x3 loop
            {
                for(int j=col-1; j<=col+1; j++)
                {
                    if(i<0||j<0||i>=height||j>=width)
                    {
                        red=0.0;blue=0.0;green=0.0;
                    }
                    else
                    {
                    red=copy[i][j].rgbtRed;
                    blue=copy[i][j].rgbtBlue;
                    green=copy[i][j].rgbtGreen;
                    Gxsum[0]+=Gx[icount][jcount]*red;
                     Gxsum[1]+=Gx[icount][jcount]*blue;
                     Gxsum[2]+=Gx[icount][jcount]*green;
                     Gysum[0]+=Gy[icount][jcount]*red;
                     Gysum[1]+=Gy[icount][jcount]*blue;
                     Gysum[2]+=Gy[icount][jcount]*green;
                    }

                     jcount++;
                }
                icount++;
            }
            finalval[0]=round(sqrt(Gxsum[0]*Gxsum[0] + Gysum[0]*Gysum[0]));//red
            finalval[1]=round(sqrt(Gxsum[1]*Gxsum[1] + Gysum[1]*Gysum[1]));//blue
            finalval[2]=round(sqrt(Gxsum[2]*Gxsum[2] + Gysum[2]*Gysum[2]));//green

            for(int k=0; k<3; k++)
            {
                if (finalval[k]>255)
                {
                    finalval[k]=255;
                }

            }

//now assign image pixel to newvals;

image[row][col].rgbtRed=(int)finalval[0];
image[row][col].rgbtBlue=(int)finalval[1];
image[row][col].rgbtGreen=(int)finalval[2];

        }
    }
    return;
}

Solution

I think your code contains compilation error and runtime error. When you execute, you are just running the version comes form the course material. Hence the result is a white image.

First, you need to #include <math.h> to use sqrt(), round(). Second, there is a logical error where you forgot to reset jcount to 0 after each row completes. When jcount becomes 3, it hit array index out of bound.

Below is my corrected, simplified version

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
    //Create Gx and Gy Matrixes
    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} };
    // max of each channel
    const int channelCap = 255;
    //create copy of image
    RGBTRIPLE copy[height][width];
    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {

            copy[row][col].rgbtBlue = image[row][col].rgbtBlue;
            copy[row][col].rgbtRed = image[row][col].rgbtRed;
            copy[row][col].rgbtGreen = image[row][col].rgbtGreen;
        }
    }
    //create loop for edge detection
    int red; int blue; int green;
    double finalRed, finalGreen, finalBlue;
    double gxRed, gxGreen, gxBlue;
    double gyRed, gyGreen, gyBlue;

    for (int row = 0; row < height; row++)//inside image loop
    {

        for (int col = 0; col < width; col++)
        {
            gxRed = 0.0; gxGreen = 0.0; gxBlue = 0.0;
            gyRed = 0.0; gyGreen = 0.0; gyBlue = 0.0;
            int icount = 0, jcount = 0;

            for (int i = row - 1; i <= row + 1; i++)//inside 3x3 loop
            {
                for (int j = col - 1; j <= col + 1; j++)
                {
                    if (i >= 0 && j >= 0 && i < height && j < width)
                    {
                        // within boundary
                        red = copy[i][j].rgbtRed;
                        blue = copy[i][j].rgbtBlue;
                        green = copy[i][j].rgbtGreen;

                        gxRed += gx[icount][jcount] * red;
                        gxBlue += gx[icount][jcount] * blue;
                        gxGreen += gx[icount][jcount] * green;
                        gyRed += gy[icount][jcount] * red;
                        gyBlue += gy[icount][jcount] * blue;
                        gyGreen += gy[icount][jcount] * green;
                    }
                    jcount++;

                }
                icount++;
                jcount = 0;
            }

            finalRed = fmin(round(sqrt(gxRed * gxRed + gyRed * gyRed)), channelCap);//red
            finalBlue = fmin(round(sqrt(gxBlue * gxBlue + gyBlue * gyBlue)), channelCap);//blue
            finalGreen = fmin(round(sqrt(gxGreen * gxGreen + gyGreen * gyGreen)), channelCap);//green

            //now assign image pixel to newvals;
            image[row][col].rgbtRed = (int)finalRed;
            image[row][col].rgbtBlue = (int)finalBlue;
            image[row][col].rgbtGreen = (int)finalGreen;

        }
    }
    return;
}

$ ./filter -e ./images/yard.bmp outfile.bmp

Result:

enter image description here

Answered By – Mr. Brickowski

Answer Checked By – Clifford M. (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.