【问题标题】:What is the correct way to apply filter to a image将滤镜应用于图像的正确方法是什么
【发布时间】:2013-12-27 22:54:17
【问题描述】:

我想知道将滤镜应用于图像的正确方法是什么。我正在阅读的图像处理教科书仅讨论了过滤器的数学和理论方面,而没有过多讨论其中的编程部分!

我想出了这个伪代码,有人可以告诉我它是否正确,因为我将 sobel 边缘过滤器应用于图像并且我对输出不满意。我认为它检测到许多不必要的点作为边缘,并错过了沿边缘的几个点。

int filter[][] = {{0d,-1d,0d},{-1d,8d,-1d},{0d,-1d,0d}};// I dont exactly remember the       //sobel filter
int total = 0;
for(int i = 2;i<image.getWidth()-2;i++)
    for(int j = 2;j<image.getHeight()-2;j++)
    {
        total = 0;

        for(int k = 0;k<3;k++)
            for(int l = 0;l<3;l++)
            {
                total += intensity(image.getRGB(i,j)) * filter[i+k][j+l];
            }

        if(total >= threshold){
        image.setRGB(i,j,WHITE);
    }
}

int intensity(int color)
{
    return (((color >> 16) & 0xFF) + ((color >> 8) & 0xFF) + color)/3;
}

【问题讨论】:

    标签: image-processing imagefilter


    【解决方案1】:

    两个问题:

    (1)sober operator包括x方向和y方向,它们是 int filter[][] = {{1d,0d,-1d},{2d,0d,-2d},{1d,0d,-1d}};

    int filter[][] = {{1d,2d,1d},{0d,0d,0d},{-1d,-2d,-1d}};
    

    (2)卷积部分:

    total += intensity(image.getRGB(i+k,j+l)) * filter[k][l];
    

    【讨论】:

      【解决方案2】:

      您的代码在我看来并不安静。为了将过滤器应用于图像,您必须应用离散时间卷积算法http://en.wikipedia.org/wiki/Convolution

      当您进行卷积时,您希望在图像上滑动 3x3 滤镜,一次移动一个像素。在每个步骤中,您将过滤器“像素”的值乘以该特定过滤器“像素”下的图像像素的相应值(过滤器下的 9 个像素都受到影响)。生成的值应随时添加到新的生成图像中。

      阈值是可选的...

      以下是你的代码修改了一些注释:

      int filter[][] = {{0d,-1d,0d},{-1d,8d,-1d},{0d,-1d,0d}};
      
      //create a new array for the result image on the heap
      int newImage[][][3] = ...
      
      //initialize every element in the newImage to 0
      for(int i = 0;i<image.getWidth()-1;i++)
          for(int j = 0;j<image.getHeight()-1;j++)
              for (int k = 0; k<3; k++)
              {
                  newImage[i][j][k] = 0;
              }    
      
      //Convolve the filter and the image
      for(int i = 1;i<image.getWidth()-2;i++)
          for(int j = 1;j<image.getHeight()-2;j++)
          {
              for(int k = -1;k<2;k++)
                  for(int l = -1;l<2;l++)
                  {
                      newImage[i+k][j+l][1] += getRed(image.getRGB(i+k ,j+l)) * filter[k+1][l+1];
                      newImage[i+k][j+l][2] += getGreen(image.getRGB(i+k ,j+l)) * filter[k+1][l+1];
                      newImage[i+k][j+l][3] += getBlue(image.getRGB(i+k ,j+l)) * filter[k+1][l+1];
                  }
          }
      
      int getRed(int color)
      {
          ... 
      }
      
      int getBlue(int color)
      {
          ...
      }
      
      int getGreen(int color)
      {
          ...
      }
      

      请注意,上面的代码不能完全正确地处理图像的边缘。如果你想让它绝对完美,你可以先将滤镜大部分滑出屏幕(所以第一个位置会将滤镜的右下角应用于图像的 0,0 像素。这样做真的很痛苦不过,通常忽略边缘周围的 2 像素边框更容易。

      一旦你得到这个工作,你可以通过在水平方向然后垂直方向滑动 Sobel 过滤器来进行实验。您会注意到过滤器在垂直于行进方向(过滤器)的线上作用最强。因此,为了获得最佳效果,先在水平方向应用过滤器,然后在垂直方向应用过滤器(使用相同的 newImage)。这样,您将同样好地检测垂直线和水平线。 :)

      【讨论】:

      • "在每一步中,您将过滤器“像素”的值乘以该特定过滤器“像素”下的图像像素的相应值(过滤器下的 9 个像素都受到影响) “我在很多关于卷积的材料中都发现了这种说法。我之前在 SO 中问过一个关于此的问题,我发现这有点模棱两可,我们是否需要将像素值乘以过滤器或获取像素颜色的强度,然后像我的代码中那样乘以过滤器。如果你有一个不平衡的过滤器,我发现它会导致出血效果,就像绿色会影响红色一样
      • 如果您希望将滤镜直接应用于彩色图像,我认为这样做的方法是将其独立应用于每个颜色通道(使用的值是每个相应像素颜色的值)。然后,在给定新的 R G 和 B 图像分量的情况下重构一个新图像。我猜使用图像灰度版本的问题是不同颜色的像素可能具有相似的亮度......
      • 我认为 lennon310 版本的卷积可能是等效的(昨天正在考虑这个问题),除了我会将结果应用于新图像而不覆盖原始图像。他所说的关于过滤器的事情也是正确的。我必须自己玩一下,看看,已经有一段时间了。
      • 如果我在 9 个位置 {0,255,0},{255,2,255},{0,255,0} 中有以下绿色值(让图像为 3 X 3个正方形,9个位置的绿色值如图所示)应用过滤器以绿色为2的像素为中心,我得到绿色值为-255 * 4 + 2我应该如何处理它? A)它的负 B)它大于 255 我应该只考虑低位还是高位?
      • 尝试将小于0的值截断为0,大于255的值截断为255。你也可以看看下面的lodev.org/cgtutor/filtering.html
      【解决方案3】:

      这里发生了一些严重的未定义行为。数组 filter 是 3x3,但您使用的下标 i+kj+l 取决于图像的大小。看起来你放错了这个添加:

      total += intensity(image.getRGB(i+k,j+l)) * filter[k][l];
      

      【讨论】:

        【解决方案4】:

        使用GPUImage,对你来说挺不错的。

        【讨论】:

        • 我正在学习图像处理,所以我宁愿不依赖任何库!
        猜你喜欢
        • 2011-05-14
        • 2014-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-18
        相关资源
        最近更新 更多