将线性滤波器应用于图像(实现imfilter)而不影响速度和性能

时间:2013-06-27 21:47:33

标签: performance matlab image-processing time

基于this codethis one我熟悉实现imfilter函数。但是你知道这些代码(使用顺序for循环)在matlab中会非常慢,特别是对于高分辨率图像并且它们在其他编程语言中更有效。在matlab中,最好尽可能地对代码进行矢量化 任何人都可以建议我一种矢量化imfilter实现的方法吗? 注意:我知道我可以使用edit('imfilter')来研究开发人员用来实现imfilter函数的代码,但这对我来说很难。我不太了解这些代码。我是matlab的新手 注意:我知道作为示例引入的代码的某些部分可以非常容易地进行矢量化,因此可以更容易地实现this code中的示例填充部分。 但我正在考虑将代码的主要部分(应用过滤器的一部分)进行矢量化。我指的是图片中显示的部分:
enter image description here
enter image description here
我不知道如何对这些部件进行矢量化? 哦,我忘了告诉我已经为this question.编写了接受的答案。如果我也不想使用conv2函数,有什么办法吗?

2 个答案:

答案 0 :(得分:3)

只有你的功能...它被称为im2col。有关说明,请参阅http://www.mathworks.com/help/images/ref/im2col.html。它允许您将图像的“块”转换为“列” - 如果您要查找3x3块进行过滤,则每列将长度为9个元素。之后,过滤操作可以非常简单。这是一个例子:

n = 20; m = 30
myImg = rand(n, m)*255;
myImCol = im2col(myImg, [3 3], 'sliding');
myFilter = [1 2 1 2 4 2 1 2 1]';
myFilter = myFilter / sum(myFilter(:)); % to normalize
filteredImage = reshape( myImCol' * myFilter, n-2, m-2);

没有使用conv2,也没有使用任何显式循环。然而,这确实产生了一个比图像大得多的中间矩阵(在这种情况下,几乎是9倍)。这本身就是一个问题。

免责声明:我通常在发布前测试Matlab代码,但无法连接到许可证服务器。如果你遇到问题,请告诉我!

编辑为您做进一步的澄清

1)为什么要重塑n-2m-2?好吧 - im2col函数只返回它可以创建的块的“完整”列。当我创建3x3块时,我可以制作的第一个以(2,2)为中心,最后一个在(end-1,end-1)上。因此,结果比原始图像略小 - 它就像“填充”一样。事实上,这与使用conv2时发生的情况完全相反 - 在这种情况下,事情会得到扩展。如果您想避免这种情况,可以先使用

扩展您的图像
paddedIm = zeros(n+2, m+2);
paddedIm(2:end-1, 2:end-1) = myImg;

并在填充图像上运行过滤器。

2)'sliding''distinct'之间的区别最好用一个例子来解释:

>> M = magic(4)

M =

16     2     3    13
 5    11    10     8
 9     7     6    12
 4    14    15     1

>> im2col(M,[2 2], 'distinct')

ans =

 16     9     3     6
  5     4    10    15
  2     7    13    12
 11    14     8     1

xx--  --xx  ----  ----
xx--  --xx  ----  ----
----  ----  xx--  --xx
----  ----  xx--  --xx

>> im2col(M,[2 2], 'sliding')

ans =

 16     5     9     2    11     7     3    10     6
  5     9     4    11     7    14    10     6    15
  2    11     7     3    10     6    13     8    12
 11     7    14    10     6    15     8    12     1

xx--  ----  ----  -xx-
xx--  xx--  ----  -xx-      ... etc ...
----  xx--  xx--  ----
----  ----  xx--  ----

如您所见,'distinct'选项返回非重叠块:'sliding'选项返回“所有适合的块”,即使有些块会重叠。

3)conv2的实现可能是一些较低级别的速度代码 - 您可能知道.mex文件,它们允许您编写自己的C代码,可以与Matlab链接并为您提供一个很大的速度优势?这可能就是这样的。他们在他们的网站上声称他们使用“直接实现” - 因此速度很可能只是快速实施(而不是“高效的Matlab”)。

答案 1 :(得分:1)

两个内部循环可以通过 -

进行矢量化
orignalFlip=flipud(fliplr(orignal(i-1:i+1,j-1:j+1)));
temp=orignalFlip.*filter;

但是' conv2' ?似乎正是你需要的......

但是,你不应该在matlab中做4个嵌套循环。