【问题标题】:simple blur of RGB raw imageRGB原始图像的简单模糊
【发布时间】:2012-09-29 05:26:52
【问题描述】:

我正在尝试在 c 中制作一个简单的模糊效果。我在 512*512 RGB 像素数组中加载了一个图像,我正在使用 3x3 内核来模糊该图像

这是内核

float matrix[9] = {1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f, 1.0f/9.0f};

这是进行模糊处理的代码

void useBlur(){

  for(int i = 0; i < ARRAY_SIZE; i++){
      float r = 0;
      float g = 0;
      float b = 0;
      int m, n;

      for(int y = -1,  m = 0; y <= 1; y++, m++){
          for(int z = -1,  n = 0; z <= 1; z++, n++){
              r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n];
              g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n];
              b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n];
          }

      }

      image[i].r = r;
      image[i].g = g;
      image[i].b = b;

  }
}

我不确定该代码有什么问题,但它正在产生结果:

任何想法为什么颜色是错误的?以及如何解决?

编辑: 修复矩阵[7] 从 9.0/9.0 到 1.0/9.0 并上传新图片

【问题讨论】:

  • 我无法加载图像,但看起来你至少有一些混乱的边缘条件。就像第一次迭代一样,不是“i+512*y+z”==“0+512*(-1)+(-1)”吗?所以你的数组索引是-513?
  • 两个问题:(i) 您正在从数组边界之外读取像素,并且 (ii) 您在倒数第二个滤波器系数中有错字。
  • 是的,我已经从索引 513 开始了 for 循环,但结果是一样的,除了第一行没有画出来

标签: c opengl image-processing rgb


【解决方案1】:

我对您的代码进行了一些更改,我拥有的图像是 BGRA,并且我将 opencv 用于我的图像容器,但是代码的结构是相同的,并且可以完美运行。

    for (int i = 2*image.cols; i < image.rows*image.cols-2*image.cols; i++)
    {
        float r = 0;
        float g = 0;
        float b = 0;

        for (int y = -1; y <=1; y++)
        {
            for (int z = -1; z <=1; z++)
            {
                b += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(0)*(1.0/9);
                g += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(1)*(1.0/9);
                r += (float)image.at<cv::Vec4b>(i + image.cols*y+z)(2)*(1.0/9);
            }
        }
        image.at<cv::Vec4b>(i)(0) = b;
        image.at<cv::Vec4b>(i)(1) = g;
        image.at<cv::Vec4b>(i)(2) = r;
    }

我认为这意味着问题要么不在您发布的代码中,要么以某种方式 opencv cv::Mat 类正在处理您的图像容器没有的东西。明显的候选者是您似乎在代码末尾隐式地从 float 转换为 uchar 。你能测试在你的图像上运行这个循环但不修改它吗?它可能看起来像这样,或任何其他方式。这很难看,但转换很快。

void useBlur(){

for(int i = 0; i < ARRAY_SIZE; i++){
  float r = 0;
  float g = 0;
  float b = 0;
  int m, n;

  for(int y = -1,  m = 0; y <= 1; y++, m++){
      for(int z = -1,  n = 0; z <= 1; z++, n++){
          if(y == 0 && z == 0)
          {
            r += (float)orig_image[i + 512 * y + z].r * (float)matrix[m*3+n]*9;
            g += (float)orig_image[i + 512 * y + z].g * (float)matrix[m*3+n]*9;
            b += (float)orig_image[i + 512 * y + z].b * (float)matrix[m*3+n]*9;
          }
      }

  }

  image[i].r = r;
  image[i].g = g;
  image[i].b = b;

 }
 }

理论上,当您这样做时,图像不会发生任何变化,因此如果图像发生变化,那是因为一些转换错误。我承认这个理论不太可能,但你的代码结构似乎很合理,所以我不知道还有什么建议。

【讨论】:

  • 嗯,问题出在转换上,我已经弄清楚了,因为当我稍微修改算法时,模糊后白色变成黑色,所以我做了一点调试,发现代码是使用带符号的变量,颜色表示为 GLByte,我假设类似于 unsigned char,所以我用 (unsigned char) 替换了 (float),现在一切正常。
猜你喜欢
  • 2019-05-22
  • 2016-05-21
  • 1970-01-01
  • 2022-10-02
  • 1970-01-01
  • 2022-10-30
  • 1970-01-01
  • 2022-11-19
  • 2014-02-02
相关资源
最近更新 更多