【问题标题】:CS50 Filter - BlurCS50 滤镜 - 模糊
【发布时间】:2021-08-13 15:32:41
【问题描述】:

早安,

我已经编写了 CS50 模糊滤镜的代码,并且我知道有更好的编码方式(使用更少的 if 语句),但在重写之前,我想了解为什么它目前不起作用。它会产生一个非常暗的图像,看起来 RGB 值太低了。我被困住了,很乐意接受一些帮助。谢谢。

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE temp[height][width];
    
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int counter = 1;
            
            temp[i][j].rgbtRed = image[i][j].rgbtRed;
            temp[i][j].rgbtGreen = image[i][j].rgbtGreen;
            temp[i][j].rgbtBlue = image[i][j].rgbtBlue;
            
            if (i != height - 1)
            {
                temp[i][j].rgbtRed += image[i+1][j].rgbtRed;
                temp[i][j].rgbtGreen += image[i+1][j].rgbtGreen;
                temp[i][j].rgbtBlue += image[i+1][j].rgbtBlue;
                counter++;
            }
            if (i != 0)
            {
                temp[i][j].rgbtRed += image[i-1][j].rgbtRed;
                temp[i][j].rgbtGreen += image[i-1][j].rgbtGreen;
                temp[i][j].rgbtBlue += image[i-1][j].rgbtBlue;
                counter++;
            }
            if (j != width - 1)
            {
                temp[i][j].rgbtRed += image[i][j+1].rgbtRed;
                temp[i][j].rgbtGreen += image[i][j+1].rgbtGreen;
                temp[i][j].rgbtBlue += image[i][j+1].rgbtBlue;
                counter++;
            }
            if (j != 0)
            {
                temp[i][j].rgbtRed += image[i][j-1].rgbtRed;
                temp[i][j].rgbtGreen += image[i][j-1].rgbtGreen;
                temp[i][j].rgbtBlue += image[i][j-1].rgbtBlue;
                counter++;
            }
            if (i != 0 && j != 0)
            {
                temp[i][j].rgbtRed += image[i-1][j-1].rgbtRed;
                temp[i][j].rgbtGreen += image[i-1][j-1].rgbtGreen;
                temp[i][j].rgbtBlue += image[i-1][j-1].rgbtBlue;
                counter++;
            }
            if (i != height - 1 && j != width - 1)
            {
                temp[i][j].rgbtRed += image[i+1][j+1].rgbtRed;
                temp[i][j].rgbtGreen += image[i+1][j+1].rgbtGreen;
                temp[i][j].rgbtBlue += image[i+1][j+1].rgbtBlue;
                counter++;
            }
            if (i != height - 1 && j != 0)
            {
                temp[i][j].rgbtRed += image[i+1][j-1].rgbtRed;
                temp[i][j].rgbtGreen += image[i+1][j-1].rgbtGreen;
                temp[i][j].rgbtBlue += image[i+1][j-1].rgbtBlue;
                counter++;
            }
            if (i != 0 && j != width - 1)
            {
                temp[i][j].rgbtRed += image[i-1][j+1].rgbtRed;
                temp[i][j].rgbtGreen += image[i-1][j+1].rgbtGreen;
                temp[i][j].rgbtBlue += image[i-1][j+1].rgbtBlue;
                counter++;
            }
            image[i][j].rgbtRed = round(temp[i][j].rgbtRed / (counter * 1.0));
            image[i][j].rgbtGreen = round(temp[i][j].rgbtGreen / (counter * 1.0));
            image[i][j].rgbtBlue = round(temp[i][j].rgbtBlue / (counter * 1.0));
           
        }
    }
    
    
    return;
}

【问题讨论】:

  • 你做了什么来验证 a) 这些值应该是什么以及 b) 你的代码正在做什么来产生错误的值?
  • 尝试使用一种颜色的图像,例如 [100,100,100] 进行简单的数学运算,然后在调试器中检查您的中间结果或将它们打印出来,看看它们是否符合您的期望。
  • 使用temp[i][j].rgbtRed += image[i+1][j].rgbtRed; 等,您正在溢出(可能)8 位整数。 a) 首先将 整个 图像复制到 temp[][](或之后以其他方式),b) 使用单独的 intfloat 变量,并写入 average 进入图像数组。
  • 请提供RGBTRIPLE的定义。
  • 不需要复制整个二维数组。你不需要这么大的临时数组,你只需要那个二维数组的一个元素。

标签: c cs50


【解决方案1】:

为什么它现在不起作用。它会产生非常暗的图像

通过temp[i][j].rgbtRed += image[i+1][j].rgbtRed; 等形成的总和溢出temp[i][j].rgbtRed@Weather Vane。后面的除法将截断的和降低到黑色。

对总和使用更宽的类型。

// RGBTRIPLE temp[height][width];
int r,g,b;  // If temp[i][j].rgbtRed width less than int, else use long, etc.

for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        ...
        
            // temp[i][j].rgbtRed += image[i+1][j].rgbtRed;
            // temp[i][j].rgbtGreen += image[i+1][j].rgbtGreen;
            // temp[i][j].rgbtBlue += image[i+1][j].rgbtBlue;
            r += image[i+1][j].rgbtRed;
            g += image[i+1][j].rgbtGreen;
            b += image[i+1][j].rgbtBlue;

未经测试的候选简化:

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 r = 0;
      int g = 0;
      int b = 0;
      int counter = 0;
      for (int di = max(i - 1, 0); di < min(i + 2, height); di++) {
        for (int dj = max(j - 1, 0); dj < min(j + 2, width); dj++) {
          r += image[di][dj].rgbtRed;
          g += image[di][dj].rgbtGreen;
          b += image[di][dj].rgbtBlue;
          counter++;
        }
      }
      // simplified rounding
      image[i][j].rgbtRed = (r + counter / 2) / counter;
      image[i][j].rgbtGreen = (g + counter / 2) / counter;
      image[i][j].rgbtBlue = (b + counter / 2) / counter;
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多