CS50边缘过滤器程序无法正常运行(Sobel运算符)

问题描述 投票:0回答:1

我必须将Sobel operator应用于图像中的每个像素以进行cs50突出显示边缘,因此我创建了每个像素的副本,然后找到了该像素每种颜色的Gx和Gy值(总共6个值: gxR,gxB,gxG,gyR,gyB,gyG)。我为图片的角落或边缘上的像素创建了8个if案例(我意识到这是多余的并且非常重复,但是我自己想不到更好的解决方案)。然后,我通过对每种对应颜色(例如int blue = round(sqrt((gxB * gxB) + (gyB * gyB)));)的平方和求平方根来找到新的蓝色,绿色和红色值。我将颜色值的上限设置为255(请参见cap功能),然后将其应用于图像中的每种相应颜色。但是,当我运行时,边缘不会显示,而是会显示非常明亮的图像,并且程序不会在check50中通过任何检查。有人知道怎么了吗?

这里是错误消息(完整版here):

:( edges correctly filters middle pixel
    expected "210 150 60\n", not "255 242 207\n"
:( edges correctly filters pixel on edge
    expected "213 228 255\n", not "255 255 255\n"
:( edges correctly filters pixel in corner
    expected "76 117 255\n", not "76 134 255\n"
:( edges correctly filters 3x3 image
    expected "76 117 255\n21...", not "76 134 255\n25..."
:( edges correctly filters 4x4 image
    expected "76 117 255\n21...", not "76 134 255\n25..."

这是我的代码:

void edges(int height, int width, RGBTRIPLE image[height][width])
{
    int gxB;
    int gxG;
    int gxR;
    int gyB;
    int gyG;
    int gyR;

    // create a temporary array to store a duplicate of image.
    RGBTRIPLE temp[height][width];

    // save a new copy of image as temp per color.
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            temp[i][j] = image[i][j];
        }
    }

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            if (i == 0 && j == 0)
            {
                // top left corner 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*0 + temp[i][j + 1].rgbtBlue*2 + temp[i + 1][j + 1].rgbtBlue*1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*0 + temp[i][j + 1].rgbtGreen*2 + temp[i + 1][j + 1].rgbtGreen*1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*0 + temp[i][j + 1].rgbtRed*2 + temp[i + 1][j + 1].rgbtRed*1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*2 + temp[i][j + 1].rgbtBlue*2 + temp[i + 1][j + 1].rgbtBlue*1);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*2 + temp[i][j + 1].rgbtGreen*2 + temp[i + 1][j + 1].rgbtGreen*1);
                gyR = (temp[i][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*2 + temp[i][j + 1].rgbtRed*2 + temp[i + 1][j + 1].rgbtRed*1);
            }

            else if (i == 0 && j == (width - 1))
            {
                // top right corner 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*0 + temp[i][j - 1].rgbtBlue*-2 + temp[i + 1][j - 1].rgbtBlue*-1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*0 + temp[i][j - 1].rgbtGreen*-2 + temp[i + 1][j - 1].rgbtGreen*-1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*0 + temp[i][j - 1].rgbtRed*-2 + temp[i + 1][j - 1].rgbtRed*-1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*2 + temp[i][j - 1].rgbtBlue*0 + temp[i + 1][j - 1].rgbtBlue*1 );
                gyG = (temp[i][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*2 + temp[i][j - 1].rgbtGreen*0 + temp[i + 1][j - 1].rgbtGreen*1 );
                gyR = (temp[i][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*2 + temp[i][j - 1].rgbtRed*0 + temp[i + 1][j - 1].rgbtRed*1 );
            }

            else if (i == 0 && (j != 0 || j != (width - 1)))
            {
                // top edge 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*0 + temp[i][j - 1].rgbtBlue*-2 + temp[i][j + 1].rgbtBlue*2 + temp[i + 1][j - 1].rgbtBlue*-1 + temp[i + 1][j + 1].rgbtBlue*1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*0 + temp[i][j - 1].rgbtGreen*-2 + temp[i][j + 1].rgbtGreen*2 + temp[i + 1][j - 1].rgbtGreen*-1 + temp[i + 1][j + 1].rgbtGreen*1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*0 + temp[i][j - 1].rgbtRed*-2 + temp[i][j + 1].rgbtRed*2 + temp[i + 1][j - 1].rgbtRed*-1 + temp[i + 1][j + 1].rgbtRed*1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*2 + temp[i][j - 1].rgbtBlue*0 + temp[i][j + 1].rgbtBlue*2 + temp[i + 1][j - 1].rgbtBlue*1 + temp[i + 1][j + 1].rgbtBlue*1);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*2 + temp[i][j - 1].rgbtGreen*0 + temp[i][j + 1].rgbtGreen*2 + temp[i + 1][j - 1].rgbtGreen*1 + temp[i + 1][j + 1].rgbtGreen*1);
                gyR = (temp[i][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*2 + temp[i][j - 1].rgbtRed*0 + temp[i][j + 1].rgbtRed*2 + temp[i + 1][j - 1].rgbtRed*1 + temp[i + 1][j + 1].rgbtRed*1);
            }

            else if (i == (height - 1) && j == 0)
            {
                // bottom left corner 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*0 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*0 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*0 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*-2 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*0);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*-2 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*0);
                gyR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*-2 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*0);
            }

            else if (i == (height - 1) && j == (width - 1))
            {
                // bottom right corner 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*0 + temp[i][j - 1].rgbtBlue*-2 + temp[i-1][j - 1].rgbtBlue*-1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*0 + temp[i][j - 1].rgbtGreen*-2 + temp[i-1][j - 1].rgbtGreen*-1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*0 + temp[i][j - 1].rgbtRed*-2 + temp[i-1][j - 1].rgbtRed*-1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*-2 + temp[i][j - 1].rgbtBlue*0 + temp[i-1][j - 1].rgbtBlue*-1);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*-2 + temp[i][j - 1].rgbtGreen*0 + temp[i-1][j - 1].rgbtGreen*-1);
                gyR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*-2 + temp[i][j - 1].rgbtRed*0 + temp[i-1][j - 1].rgbtRed*-1);
            }

            else if (i == (height - 1) && (j != 0 || j != (width - 1)))
            {
                // bottom edge 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*0 + temp[i][j - 1].rgbtBlue*-2 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*1 + temp[i-1][j - 1].rgbtBlue*-1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*0 + temp[i][j - 1].rgbtGreen*-2 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*1 + temp[i-1][j - 1].rgbtGreen*-1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*0 + temp[i][j - 1].rgbtRed*-2 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*1 + temp[i-1][j - 1].rgbtRed*-1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*-2 + temp[i][j - 1].rgbtBlue*0 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*0 + temp[i-1][j - 1].rgbtBlue*-1);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*-2 + temp[i][j - 1].rgbtGreen*0 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*0 + temp[i-1][j - 1].rgbtGreen*-1);
                gyR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*-2 + temp[i][j - 1].rgbtRed*0 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*0 + temp[i-1][j - 1].rgbtRed*-1);
            }

            else if (j == 0 && (i != 0 || i != (height - 1)))
            {
                // left edge 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*0 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*1 + temp[i + 1][j + 1].rgbtBlue*1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*0 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*1 + temp[i + 1][j + 1].rgbtGreen*1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*0 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*1 + temp[i + 1][j + 1].rgbtRed*1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*-2 + temp[i + 1][j].rgbtBlue*2 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*0 + temp[i + 1][j + 1].rgbtBlue*1);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*-2 + temp[i + 1][j].rgbtGreen*2 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*0 + temp[i + 1][j + 1].rgbtGreen*1);
                gyR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*-2 + temp[i + 1][j].rgbtRed*2 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*0 + temp[i + 1][j + 1].rgbtRed*1);
            }

            else if (j == (width - 1) && (i != 0 || i != (height - 1)))
            {
                // right edge 
                gxB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*0 + temp[i][j - 1].rgbtBlue*-2 + temp[i-1][j - 1].rgbtBlue*-1 + temp[i + 1][j - 1].rgbtBlue*-1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*0 + temp[i][j - 1].rgbtGreen*-2 + temp[i-1][j - 1].rgbtGreen*-1 + temp[i + 1][j - 1].rgbtGreen*-1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*0 + temp[i][j - 1].rgbtRed*-2 + temp[i-1][j - 1].rgbtRed*-1 + temp[i + 1][j - 1].rgbtRed*-1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*-2 + temp[i + 1][j].rgbtBlue*2 + temp[i-1][j - 1].rgbtBlue*-1 + temp[i + 1][j - 1].rgbtBlue*1);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*-2 + temp[i + 1][j].rgbtGreen*2 + temp[i-1][j - 1].rgbtGreen*-1 + temp[i + 1][j - 1].rgbtGreen*1);
                gyR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*-2 + temp[i + 1][j].rgbtRed*2 + temp[i-1][j - 1].rgbtRed*-1 + temp[i + 1][j - 1].rgbtRed*1);
            }

            else
            {
                // any other pixel
                gxB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*0 + temp[i + 1][j].rgbtBlue*0 + temp[i][j - 1].rgbtBlue*-2 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*1 + temp[i-1][j - 1].rgbtBlue*-1 + temp[i + 1][j - 1].rgbtBlue*-1 + temp[i + 1][j + 1].rgbtBlue*1);
                gxG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*0 + temp[i + 1][j].rgbtGreen*0 + temp[i][j - 1].rgbtGreen*-2 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*1 + temp[i-1][j - 1].rgbtGreen*-1 + temp[i + 1][j - 1].rgbtGreen*-1 + temp[i + 1][j + 1].rgbtGreen*1);
                gxR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*0 + temp[i + 1][j].rgbtRed*0 + temp[i][j - 1].rgbtRed*-2 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*1 + temp[i-1][j - 1].rgbtRed*-1 + temp[i + 1][j - 1].rgbtRed*-1 + temp[i + 1][j + 1].rgbtRed*1);
                gyB = (temp[i][j].rgbtBlue*0 + temp[i - 1][j].rgbtBlue*-2 + temp[i + 1][j].rgbtBlue*2 + temp[i][j - 1].rgbtBlue*0 + temp[i][j + 1].rgbtBlue*2 + temp[i - 1][j + 1].rgbtBlue*0 + temp[i-1][j - 1].rgbtBlue*-1 + temp[i + 1][j - 1].rgbtBlue*1 + temp[i + 1][j + 1].rgbtBlue*1);
                gyG = (temp[i][j].rgbtGreen*0 + temp[i - 1][j].rgbtGreen*-2 + temp[i + 1][j].rgbtGreen*2 + temp[i][j - 1].rgbtGreen*0 + temp[i][j + 1].rgbtGreen*2 + temp[i - 1][j + 1].rgbtGreen*0 + temp[i-1][j - 1].rgbtGreen*-1 + temp[i + 1][j - 1].rgbtGreen*1 + temp[i + 1][j + 1].rgbtGreen*1);
                gyR = (temp[i][j].rgbtRed*0 + temp[i - 1][j].rgbtRed*-2 + temp[i + 1][j].rgbtRed*2 + temp[i][j - 1].rgbtRed*0 + temp[i][j + 1].rgbtRed*2 + temp[i - 1][j + 1].rgbtRed*0 + temp[i-1][j - 1].rgbtRed*-1 + temp[i + 1][j - 1].rgbtRed*1 + temp[i + 1][j + 1].rgbtRed*1);
            }

            int blue = round(sqrt((gxB * gxB) + (gyB * gyB)));
            int green = round(sqrt((gxG * gxG) + (gyG * gyG)));
            int red = round(sqrt((gxR * gxR) + (gyR * gyR)));

            image[i][j].rgbtBlue = cap(blue);
            image[i][j].rgbtGreen = cap(green);
            image[i][j].rgbtRed = cap(red);
        }
    }
    return;
}

最后,这是我的cap函数:

// cap function retrieved from this video: https://youtu.be/VbG8tH-Vbko
int cap(int value)
{
    return value < 255 ? value: 255;
}

这是原始图像:

Original Image

这是经过处理的我的图像:enter image description here

EDIT:按照Solancia的回答,我将temp[i - 1][j + 1].rgbtRed*0temp[i - 1][j + 1].rgbtRed*-1gyR的所有gyB实例更改为gyG。另外,我意识到对于temp[i][j + 1].rgbtRed*2gyRgyBgyG的所有实例都应为temp[i][j + 1].rgbtRed*0。更改这些允许我的代码正常运行并通过check50。我意识到我的代码很糟糕,应该拆分为多个单独的函数,但是我已经编写了它,并且不认为要拆分成多个单独的函数,直到看到无效的解决方案为止。不过,下次我会记住这一点,因此感谢您的帮助。

c pixel cs50 edges sobel
1个回答
2
投票

[好吧,马廷·乌尔哈克(Mateen Ulhaq)在上面所说的需要提高可读性的地方仍然存在。但是,作为快速解决方案,在您的else块上,您放置了:

temp[i - 1][j + 1].rgbtRed*0

对于gyR。这也适用于rgbtGreen和rgbtBlue。

应该是:

temp[i - 1][j + 1].rgbtRed*-1

更重要的是,您应该尝试将代码更改或放置在其他区域,因为这样会使人们难以阅读,因此可能会遗漏其他错误。

© www.soinside.com 2019 - 2024. All rights reserved.