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

Performance 对图像应用线性滤波器(实现imfilter)而不影响速度和性能,performance,matlab,image-processing,time,Performance,Matlab,Image Processing,Time,基于,我熟悉imfilter函数的实现。但正如您所知,这类代码(使用顺序for循环)在matlab中非常慢,特别是对于高分辨率图像,并且在其他编程语言中效率更高。在matlab中,最好尽可能多地对代码进行矢量化。 有人能给我一个矢量化imfilter实现的方法吗? 注意:我知道我可以使用edit('imfilter')来研究开发人员用于实现imfilter函数的代码,但这对我来说相当困难。我不太懂这些代码。我对matlab相当陌生。 注意:我知道作为示例介绍的部分代码可以非常容易地矢量化,因此中

基于,我熟悉imfilter函数的实现。但正如您所知,这类代码(使用顺序for循环)在matlab中非常慢,特别是对于高分辨率图像,并且在其他编程语言中效率更高。在matlab中,最好尽可能多地对代码进行矢量化。
有人能给我一个矢量化imfilter实现的方法吗?
注意:我知道我可以使用edit('imfilter')来研究开发人员用于实现imfilter函数的代码,但这对我来说相当困难。我不太懂这些代码。我对matlab相当陌生。
注意:我知道作为示例介绍的部分代码可以非常容易地矢量化,因此中的示例填充部分可以更容易地实现。
但是我正在考虑一种方法来对代码的主要部分(应用过滤器的部分)进行矢量化。我指的是图片中显示的部分:


我不知道如何将这些部分矢量化?

哦,我忘了告诉你我已经写了公认的答案,如果我也不想使用conv2函数,有什么办法吗?

两个内部循环可以通过-

orignalFlip=flipud(fliplr(orignal(i-1:i+1,j-1:j+1)));
temp=orignalFlip.*filter;
但是“conv2”有什么问题呢?看来这正是你需要的


但是,您不应该在matlab中执行4个嵌套循环。

这两个内部循环可以通过-

orignalFlip=flipud(fliplr(orignal(i-1:i+1,j-1:j+1)));
temp=orignalFlip.*filter;
但是“conv2”有什么问题呢?看来这正是你需要的


但是,您不应该在matlab中执行4个嵌套循环。

有一个函数只适合您。。。它被称为
im2col
。有关说明,请参阅。它允许您将图像的“块”转换为“列”-如果您正在寻找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);
>> 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--  ----
没有使用
conv2
,也没有使用任何显式循环。然而,这确实创建了一个比图像大得多的中间矩阵(在本例中,几乎是9倍)。这本身就是一个问题

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

为您编辑一些进一步的澄清

1) 为什么要用
n-2
m-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) 最好用一个例子来解释
'slided'
'distinct'
之间的区别:

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);
>> 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'
选项返回非重叠块:
'slided'
选项返回“适合的所有块”,即使有些块会重叠


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

有一个函数只适合你。。。它被称为
im2col
。有关说明,请参阅。它允许您将图像的“块”转换为“列”-如果您正在寻找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);
>> 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--  ----
没有使用
conv2
,也没有使用任何显式循环。然而,这确实创建了一个比图像大得多的中间矩阵(在本例中,几乎是9倍)。这本身就是一个问题

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

为您编辑一些进一步的澄清

1) 为什么要用
n-2
m-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) 最好用一个例子来解释
'slided'
'distinct'
之间的区别:

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);
>> 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'
选项返回非重叠块:
'slided'
选项返回“适合的所有块”,即使有些块会重叠


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

来自MathWorks的文章。另请参见MathWorks上的这篇文章。再看看这个。这是一个大学作业。我不应该使用内置函数