什么是实际应用过滤器?

时间:2012-04-04 00:23:21

标签: c++ algorithm image-processing

我正在尝试使用我不熟悉的概念来解决C ++中的一个具有挑战性的问题。

我正在尝试将过滤器应用于矩阵。然而就像我说的那样,我在这方面很新,经过一些调查我发现这个链接显示应用过滤器基本上是一个乘法

然而令我困惑的是,如果我的过滤器是[0,1,0]并且我必须将它应用于5x5矩阵。我怎么能这样做?

GIMP Filtering with kernel

An alternative to first link

编辑:第二个链接让我很困惑。我现在正试图决定“申请”流程。如果我遵循创建一个只有对角线[0,1,0]的3x3矩阵的想法,我将像第二个链接一样应用它,或者我是否必须将它应用于矩阵中的每个单元格。或者,如果它真的将成为一维滤波器,我是否应该再将它应用于每个单元格或者省去边缘和角落?

4 个答案:

答案 0 :(得分:4)

这是一个卷积内核。

这个想法是你用它和它的邻居的加权平均值替换每个像素,其中权重由你的卷积内核给出。该过程很好地解释,例如here

我觉得奇怪的是你有一个1-D卷积内核(即适用于一维图像),通常用于图像处理2-D卷积内核(它也取自上/下行的像素) ),但可能是你的算法只需要处理当前行的像素。

答案 1 :(得分:3)

我认为被忽略的是使用输入数据的子集对输入数组的每个元素重复乘法。

GIMP示例展示了如何使用3x3滤镜为单个像素过滤5x5图像:

. . . . .                  . . . . .
. - - - .     . . .        . . . . .
. - @ - .  x  . . .   ->   . . @ . . 
. - - - .     . . .        . . . . .
. . . . .                  . . . . .

我用一个@标记了一个输入像素,用-标记了它的邻居。您使用较小的矩阵:

- - -     . . .
- @ -  x  . . .  = 3x3 array
- - -     . . .

将得到的3x3数组中的数字相加,并将该值存储到 new 图像中,代替@像素。

在使用3x1过滤器过滤5x5图像时,以此为例:

. . . . .                  . . . . .
. . . . .                  . . . . .
. - @ - .  x  . . .   ->   . . @ . . 
. . . . .                  . . . . .
. . . . .                  . . . . .

您将使用较小的输入数组子集来匹配您的内核;

- @ -  x  . . .  = 1x3 array

然后,再次对结果数组中的数字求和,并将该值存储到新图像中以代替@像素。

答案 2 :(得分:2)

在答案中,你正在寻找的东西令人困惑。如果我们假设您的过滤器存储在名为std::vector<double>的{​​{1}}中并且您的图片确实是2D并且类型filter名为std::vector< std::vector<double> >,那么我们可以执行以下是应用1-D过滤器image

[-1,0,1]

如果您想要像这样的二维滤镜,例如

 std::vector< std::vector<double> > new_image;
 std::vector<double> filter;
 filter.push_back(-1.0); filter.push_back(0.0); filter.push_back(1.0);

 for(int i = 0; i < image.size(); i++){
     for(int j = 0; j < image.at(i).size(); j++){

         new_image.at(i).push_back( filter.at(0)*image.at(i).at(j-1)
                                    + filter.at(1)*image.at(i).at(j)
                                    + filter.at(2)*image.at(i).at(j+1) );

     }
 }

然后我们假设它也被存储为向量的向量,并且基本上也是这样做的。

 [0 1 0]
 [1 0 1]
 [0 1 0]

请注意 - 我没有做任何努力来检查过滤器阵列的边界,你真的应该只从图像的边缘应用它,或者添加代码为您的过滤器应用您想要的任何类型的边界条件。我也没有对此进行优化提出任何要求。在大多数情况下,使用向量是一种很好的方法,因为它们可以动态调整大小并提供足够的内置支持来执行大量有用的图像处理。但对于真正的大规模处理,您需要优化过滤操作等内容。

关于过滤3D阵列的问题,有几点需要考虑。一,确保你真的想要过滤整个阵列。对于许多图像处理任务,将所有颜色通道分割为自己的2D阵列,进行处理,然后将它们重新组合在一起会更好,更有效。如果你想要一个真正的3D滤镜,那么请确保你的滤镜实际上是3D,也就是说,它将是矢量矢量的矢量。然后,您将使用与上面完全相同的逻辑,但是您应该为应用于每个颜色通道的过滤器部分添加一个额外的术语层,或者&#34;切片&#34;,图像。

答案 3 :(得分:0)

我认为你在谈论滤色镜。从技术上讲,5X5图像实际上是5X5X3(A),其中“3”对应于3种基本颜色(RGB)。现在,创建一个3X3的矩阵,对角线为[0,1,0](T)。

现在将两个矩阵(AXT)相乘得到新的5X5X3图像矩阵。