CS50 - PSet4(滤镜) - 模糊

煎饼先生

我正在运行以下代码

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int div = 1;

            if ( j + 1 < width - 1 && j + 1 > 0)
            {
                div++;
            }
            else
            {
                image[i][j + 1].rgbtRed = 0;
                image[i][j + 1].rgbtRed = 0;
                image[i][j + 1].rgbtRed = 0;
            }
             if ( i + 1 < height - 1 && i + 1 > 0)
            {
                div++;
            }
            else
            {
                image[i + 1][j].rgbtRed = 0;
                image[i + 1][j].rgbtRed = 0;
                image[i + 1][j].rgbtRed = 0;
            }
             if ( j + 1 < width - 1 && j + 1 > 0 && i + 1 < height - 1 && i + 1 > 0)
            {
                div++;
            }
            else
            {
                image[i + 1][j + 1].rgbtRed = 0;
                image[i + 1][j + 1].rgbtRed = 0;
                image[i + 1][j + 1].rgbtRed = 0;
            }
            if ( i - 1 < height - 1 && i - 1 > 0)
            {
                div++;
            }
            else
            {
                image[i - 1][j].rgbtRed = 0;
                image[i - 1][j].rgbtRed = 0;
                image[i - 1][j].rgbtRed = 0;
            }
            if ( i - 1 < height - 1 && i - 1 > 0 && j + 1 < width - 1 && j + 1 > 0)
            {
                div++;
            }
            else
            {
                image[i - 1][j + 1].rgbtRed = 0;
                image[i - 1][j + 1].rgbtRed = 0;
                image[i - 1][j + 1].rgbtRed = 0;
            }
             if ( j - 1 < width - 1 && j - 1 > 0)
            {
                div++;
            }
             else
            {
                image[i][j - 1].rgbtRed = 0;
                image[i][j - 1].rgbtRed = 0;
                image[i][j - 1].rgbtRed = 0;
            }
              if ( j - 1 < width - 1 && j - 1 > 0 && i + 1 < height - 1 && i + 1 > 0)
            {
                div++;
            }
            else
            {
                image[i + 1][j - 1].rgbtRed = 0;
                image[i + 1][j - 1].rgbtRed = 0;
                image[i + 1][j - 1].rgbtRed = 0;
            }
             if ( j - 1 < width - 1 && j - 1 > 0 && i - 1 < height - 1 && i - 1 > 0)
            {
                div++;
            }
            else
            {
                image[i - 1][j - 1].rgbtRed = 0;
                image[i - 1][j - 1].rgbtRed = 0;
                image[i - 1][j - 1].rgbtRed = 0;
            }
            int averageR = (float)(image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i][j - 1].rgbtRed + image[i + 1][j].rgbtRed + image[i - 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i + 1][j - 1].rgbtRed) / div;
            int averageG = (float)(image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i - 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen) / div;
            int averageB = (float)(image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i - 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue) / div;
        image[i][j].rgbtRed = round(averageR);
        image[i][j].rgbtGreen = round(averageG);
        image[i][j].rgbtBlue = round(averageB);
        }
    }
    return;
}

不幸的是,每次我尝试在模糊部分运行它时,都会出现以下消息:

UndefinedBehaviorSanitizer:DEADLYSIGNAL
==8771==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7f7a4ec2890a (pc 0x000000427faa bp 0x7ffd07cd9170 sp 0x7ffd07cd7560 T8771)
==8771==The signal is caused by a WRITE memory access.
    #0 0x427fa9  (/home/ubuntu/pset4/filter/filter+0x427fa9)
    #1 0x4232b1  (/home/ubuntu/pset4/filter/filter+0x4232b1)
    #2 0x7f7a4db1bb96  (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #3 0x402dd9  (/home/ubuntu/pset4/filter/filter+0x402dd9)

UndefinedBehaviorSanitizer can not provide additional info.
==8771==ABORTING

知道这可能是什么吗?

罗伯托·卡博尼

您访问的内容超出了image二维数组的范围

这发生在几个点上。

考虑你的循环:

for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        
    }
}

ij是可以分别从 0 和height0 和0 变化的索引width

但是对于这两个循环,您都可以超出此限制访问。例如,如果j = width-1

if ( j + 1 < width - 1 && j + 1 > 0)
{
    div++;
}
else
{
    image[i][j + 1].rgbtRed = 0;
    image[i][j + 1].rgbtRed = 0;
    image[i][j + 1].rgbtRed = 0;
}

第一个条件不会为真 as width-1+1 > width -1,因此您最终else将进入您将访问的部分

image[i][width].rgbtRed = 0;

那是越界了!
并且在任何时候都会发生同样的情况i = height-1:诸如image[i + 1][j]将访问的

image[height][j].rgbtRed = 0;

这也是越界的。

越界访问数组会导致未定义行为,这就是您的消毒剂检测到的。


注意:虽然它与您要求的错误无关,但您可能还想更正错误

image[i][j + 1].rgbtRed = 0;
image[i][j + 1].rgbtRed = 0;
image[i][j + 1].rgbtRed = 0;

并在整个功能的类似部分。请注意,只有红色级别受到影响(三倍!);我想你也打算影响GreenBlue,而不是。


如何进行

为您实现整个功能超出了这个问题的范围,但我会尝试建议如何继续。

对于每个像素,您当前

  1. 计算不在图像边缘的元素 ( div++)
  2. 将不应对平均值做出贡献的元素设置为 0(实际上超出范围并导致您未定义的行为)
  3. 将像素周围元素的所有值(包括您设置为 0 的值)相加并除以 div

但是是什么迫使您对所有元素求和?只需总结那些真正有用的!你已经有一个正确的地方来执行这个总和:它是你 increment 的地方div

类似的东西:

for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        int div = 1;
        int curRedSum = 0, curGReenSum = 0, curBlueSum = 0;

        if ( j + 1 < width - 1 && j + 1 > 0)
        {
            div++;
            curRedSum   += image[i][j + 1].rgbtRed;
            curGreenSum += image[i][j + 1].rgbtGreen;
            curBlueSum  += image[i][j + 1].rgbtBlue;
        }

        if ( i + 1 < height - 1 && i + 1 > 0)
        {
            div++;
            curRedSum   += image[i+1][j].rgbtRed;
            curGreenSum += image[i+1][j].rgbtGreen;
            curBlueSum  += image[i+1][j].rgbtBlue;
        }
        /* ... */
        float averageR = (float)(curRedSum / ( float )div );
        float averageG = (float)(curGreenSum / ( float )div );
        float averageB = (float)(curBlueSum / ( float )div );

        image[i][j].rgbtRed = round(averageR);   // Shouldn't this assignemnt be performed on a copy of the image?
        image[i][j].rgbtGreen = round(averageG); // Shouldn't this assignemnt be performed on a copy of the image?
        image[i][j].rgbtBlue = round(averageB);  // Shouldn't this assignemnt be performed on a copy of the image?
    }
}

免责声明:这个建议应该只是一个提示。我不保证这会在没有任何进一步调整的情况下编译和工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章