CS50 滤镜 - 模糊

CS50 Filter - Blur

美好的一天,

我已经编写了 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;
}

why it doesn't work at the moment. It produces a very dark image

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

对总和使用更宽的类型。

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