【问题标题】:CS50 week 4 Filter-less Blur FunctionCS50 week 4 无滤镜模糊功能
【发布时间】:2023-01-26 04:24:40
【问题描述】:

我花了几天时间试图弄清楚这个函数有什么问题。它实际上编译得很好,但它以错误的方式模糊了图像。我相信也许我的数字或公式是错误的,但在反复检查几个小时后,我无法弄清楚哪里出了问题。

该练习要求您使用 3*3 模糊框模糊图像,因此将模糊框的 RGB 值相加并将它们除以有效模糊框像素(图像边界一侧的像素)。然后分配“模糊”图像的值。

在我模糊的图像中,模糊不允许区分图片中的任何图形。我检查了其他模糊函数的答案,并尝试用不同的变体从头开始制作和重新制作代码,但似乎没有任何效果。下面的代码在我看来它更接近正确的解决方案。 任何帮助将不胜感激。 抱歉我的英语有任何错误

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{    // create image copy for holding modifies RGB values
     RGBTRIPLE copy[height][width];
     for(int i = 0; i < height; i++)
     {
         for (int j = 0; j < width; j++)
         {
              copy[i][j] = image[i][j];
         }
     }
     // setting variable for holding sum of blur box RGB values
     float blurred = 0.0;
     float blurgreen = 0.0;
     float blurblue = 0.0;
     // setting counter for valid blur box pixels
     float validpixels = 0.0;
     // looping through image rows
     for( int i = 0; i < height; i++)
     {   // looping through image columns
         for(int j = 0; j < width; j++)
         {   // looping through blur box rows
             for(int r = -1; r < 2; r++)
             {   //looping through blur box columns
                 for(int c = -1; c < 2; c++)
                 {   // counting only valid blur-box pixels(inside image boundaries)
                     if(i + c >= 0 && j + r >= 0 && i + c < height && j + r < width)
                     {  // storing total of blur box RGB values
                        blurred += copy[i + c][j + r].rgbtRed;
                        blurgreen += copy[i + c][j + r].rgbtGreen;
                        blurblue += copy[i + c][j + r].rgbtBlue;
                        // counting valid pixels total
                        validpixels ++;
                     }
                 }
             }
               // calculate RGB  blurred values and assigning them to image copy
               copy[i][j].rgbtRed = round(blurred / validpixels);
               copy[i][j].rgbtGreen = round(blurgreen / validpixels);
               copy[i][j].rgbtBlue = round(blurblue / validpixels);
         }
     }
     //giving blur values back to image
     for(int i = 0; i < height; i++)
     {
         for (int j = 0; j < width; j++)
         {
              image[i][j].rgbtRed = copy[i][j].rgbtRed;
              image[i][j].rgbtGreen = copy[i][j].rgbtGreen;
              image[i][j].rgbtBlue = copy[i][j].rgbtBlue;
         }
     }
    return;
}

【问题讨论】:

  • "I spent several day" 你应该开始在调试器中运行你的程序。在观察变量变化的同时单步执行代码应该会很快发现这些明显的错误。盯着代码看可能会解决问题,但没有必要浪费时间这样做。
  • 您可以添加原始图像的图像和带有您要达到的结果的图像吗?

标签: c cs50 blur


【解决方案1】:

你有两个主要问题:

  • 您必须重新初始化您的blur* 变量以及每个像素的计数器。否则你会不断总结越来越多的像素。当你到达终点时,这基本上会创建整个图像的平均值。
  • 您将模糊值存储在读取要模糊的值的同一数组中。这完全泄露了制作副本的全部目的。

不是问题,但可以改进:

  • 不要在你的程序中使用float。除非您在内存或计算能力方面有一些非常严格的限制,否则您应该始终使用 double 作为浮点数。
  • 计数器最好定义为整数,而不是浮点数。

修复在代码中使用//####标记

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{    // create image copy for holding modifies RGB values
     RGBTRIPLE copy[height][width];
     for(int i = 0; i < height; i++)
     {
         for (int j = 0; j < width; j++)
         {
              copy[i][j] = image[i][j];
         }
     }

     // looping through image rows
     for( int i = 0; i < height; i++)
     {   // looping through image columns
         for(int j = 0; j < width; j++)
         {   // looping through blur box rows

             // setting variable for holding sum of blur box RGB values
             //#### Initialize your blurring variables for each pixel you are visiting.
             //#### Always use double instead of float except you have specific requirements.
             double blurred = 0.0;
             double blurgreen = 0.0;
             double blurblue = 0.0;

             // setting counter for valid blur box pixels
             //#### Also re-initialize counter for each pixel
             //#### Counters are normally integers, no floating point numbers
             size_t validpixels = 0;

             for(int r = -1; r < 2; r++)
             {   //looping through blur box columns
                 for(int c = -1; c < 2; c++)
                 {   // counting only valid blur-box pixels(inside image boundaries)
                     if(i + c >= 0 && j + r >= 0 && i + c < height && j + r < width)
                     {  // storing total of blur box RGB values
                        blurred += copy[i + c][j + r].rgbtRed;
                        blurgreen += copy[i + c][j + r].rgbtGreen;
                        blurblue += copy[i + c][j + r].rgbtBlue;
                        // counting valid pixels total
                        validpixels ++;
                     }
                 }
             }
               // calculate RGB  blurred values and assigning them to image copy
               //#### No! Don't store in the copy again. This will disturb
               //#### calculation of the other pixels. 
               image[i][j].rgbtRed = round(blurred / validpixels);
               image[i][j].rgbtGreen = round(blurgreen / validpixels);
               image[i][j].rgbtBlue = round(blurblue / validpixels);
         }
     }
     //giving blur values back to image
     //#### No! Copying again is not required. Results were stored there already

    return;
}

【讨论】:

  • 考虑使用 lround() 而不是 round(),因为目标是一个整数。
【解决方案2】:

任何帮助将不胜感激。

不是解决问题,而是简化。

 //for(int i = 0; i < height; i++) {
 //    for (int j = 0; j < width; j++) {
 //         copy[i][j] = image[i][j];
 //    }
 //}
 memcpy(copy, image, sizeof copy);

同样,最终副本返回image

memcpy(image, copy, sizeof copy);

不要使用 float 数学,而是使用整数数学。

 // float blurred = 0.0;
 unsigned blurred = 0;
 // float validpixels = 0.0;
 size_t validpixels = 0;
  
   ...
   // Leave as is.
   blurred += copy[i + c][j + r].rgbtRed;
   ... 
      // copy[i][j].rgbtRed = round(blurred / validpixels);
      copy[i][j].rgbtRed = (blurred + validpixels/2) / validpixels;

【讨论】:

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