3

我正在尝试在 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 并上传新图像

4

1 回答 1

3

我尝试了您的代码进行了一些更改,我拥有的图像是 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;

 }
 }

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

于 2012-10-08T23:39:16.897 回答