2

I'm trying to figure why my code doesn't work for detecting edges. Even though it produces a result, it is too white. Any suggestions?

// Detect edges
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}};

// loop through each row and each pixel of the image
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        int redx = 0;
        int greenx = 0;
        int bluex = 0;
        int redy = 0;
        int greeny = 0;
        int bluey = 0;

        // loop through the pixels 1 row and 1 column from the pixel
        for (int k = 0; k < 3; k++)
        {
            for (int l = 0; l < 3; l++)
            {
                // consider pixels in edges
                if (i - 1 + k < 0 || i - 1 + k > height - 1 || j - 1 + l < 0 || j - 1 + l > width - 1)
                {
                    continue;
                }

                // calcuate Gx for each color
                redx = redx + (image[i - 1 + k][j - 1 + l].rgbtRed * Gx[k][l]);
                greenx = greenx + (image[i - 1 + k][j - 1 + l].rgbtGreen * Gx[k][l]);
                bluex = bluex + (image[i - 1 + k][j - 1 + l].rgbtBlue * Gx[k][l]);

                // calculate Gy for each color
                redy = redy + (image[i - 1 + k][j - 1 + l].rgbtRed * Gy[k][l]);
                greeny = greeny + (image[i - 1 + k][j - 1 + l].rgbtGreen * Gy[k][l]);
                bluey = bluey + (image[i - 1 + k][j - 1 + l].rgbtBlue * Gy[k][l]);
            }
        }
        // calculate square root of Gx2 + Gy2 for each color
        float r = sqrt((redx * redx) + (redy * redy));
        float g = sqrt((greenx * greenx) + (greeny * greeny));
        float b = sqrt((bluex * bluex) + (bluey * bluey));

        // round to nearest integer and cap at 255
        int red =  round(r);
        int green = round(g);
        int blue = round(b);

        if (red > 255)
            red = 255;
        if (green > 255)
            green = 255;
        if (blue > 255)
            blue = 255;

        // replace color values with new value
        image[i][j].rgbtRed = red;
        image[i][j].rgbtBlue = blue;
        image[i][j].rgbtGreen = green;
    }
}
return;

}

3
  • maybe you need to cap values that are lower than 0 like you cap them when they are higher than 255? Even if it is not the solution, it still is a problem with the code. – Neslihan Kara Jul 13 '20 at 23:01
  • thanks for the answer, I submitted this pset a while ago but maybe someone who is facing the same issue now can try this and let us know if it solves the problem. – Marianna Jul 15 '20 at 8:58
  • Just wanted to say your way of calculating Gx and Gy using a two-dimension int array is brilliant! My solution is way too long since I literally calculated Gx and Gy one at a time. Thank you for your post! – Chen Yang Sep 29 '20 at 21:44
1

I found the solution, it turns out I was supposed to create a copy of the original image to work on.

2
  • I have the same issue! what do you mean with creating a copy of the image? – Juan David Garcia Hernandez Apr 8 '20 at 20:01
  • @JuanDavidGarciaHernandez I made a copy of the image like so and then calculated Gx and Gy for the copy instead of the original RGBTRIPLE copy[height][width]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { copy[i][j] = image[i][j]; } } – Marianna Apr 13 '20 at 9:20
0

I had the same issue and tried to solve it with by temporarily storing the values (like in blur) but that didn't work ... so I now solved this like you, but tbh I don't really get why this works :/. Could you explain this to me?

2
  • Hi @KapelleA, as I understand it if you work on the original image then the image is changed as you iterate over it. So in the next iteration you calculate a number that is a bit different than expected. If you work on a copy and then replace the numbers in the original image, the calculations are not affected. – Marianna May 11 '20 at 21:32
  • This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation. - From Review – MARS Jun 18 '20 at 14:17
0

The code you used does not create a separate temporary memory for the changes that you make to the image. As your code uses data stored in previous pixel as reference to edit the image, it creates a distortion rather than checking for edges.

 // replace color values with new value
        image[i][j].rgbtRed = red;
        image[i][j].rgbtBlue = blue;
        image[i][j].rgbtGreen = green;

It is better to create a copy of your edited image in a separate array to complete the editing of each and every pixel of the image without disturbing the original image.

RGBTRIPLE temp_array[height][width]; 
for (int a = 0; i < height; i++) //loop check for height
 { 
    for (int b = 0; j < width; j++) //loop check foe width
      { 
         temp_array[a][b] = image[a][b]; //storing image in temporary array
      } 
 }

Here are some screenshots for reference

Image before using temporary array

enter image description here

Image after using temporary array

enter image description here

2
  • Hi, I did the temporary array for the same image, and it turned out somewhat similar to yours but more messy in a sense, like the tree leaves are not highlighted white like yours but more of purplish and greenish mixed @Crisp_Coder99 – Kaijie Wan Jan 2 at 16:15
  • Hi, the difference in color schemes would be mostly due to some variations in code syntax mathematically (incorrect implementation of edge detection formula). Note if you are getting the correct output (after using check50) such differences can be neglected. If you found the answer and comment helpful, upvoting them both would be highly appreciated. @KaijieWan – Crisp_Coder99 Jan 5 at 13:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .