我有个问题。我有一个矩阵A,其整数值在0到5之间。
例如:

x=randi(5,10,10)

现在,我要调用一个大小为3x3的过滤器,该过滤器为我提供了最常见的值

我已经尝试了2个解决方案:
fun = @(z) mode(z(:));
y1 = nlfilter(x,[3 3],fun);

这需要很长时间...


y2 = colfilt(x,[3 3],'sliding',@mode);

这也需要很长时间。
我有一些非常大的矩阵,并且两种解决方案都需要很长时间。
有没有更快的方法?

最佳答案

+1到@Floris以获得使用 hist 的绝佳建议。非常快。您可以做得更好。 hist基于 histc ,可以代替使用。 histc是一个编译函数,即不是用Matlab编写的,这就是为什么解决方案要快得多的原因。

这是一个小函数,试图概括@Floris所做的事情(该解决方案还返回向量而不是所需的矩阵),并使用nlfilter colfilt 完成您的工作。不需要输入具有特定尺寸,并使用 im2col 有效地重新排列数据。实际上,前三行以及对im2col的调用实际上与colfit在您的情况下所做的相同。

function a=intmodefilt(a,nhood)
[ma,na] = size(a);
aa(ma+nhood(1)-1,na+nhood(2)-1) = 0;
aa(floor((nhood(1)-1)/2)+(1:ma),floor((nhood(2)-1)/2)+(1:na)) = a;
[~,a(:)] = max(histc(im2col(aa,nhood,'sliding'),min(a(:))-1:max(a(:))));
a = a-1;

用法:
x = randi(5,10,10);
y3 = intmodefilt(x,[3 3]);

对于大型阵列,这比我的机器上的colfilt快75倍以上。用hist替换histc是导致两个加速的原因。当然没有输入检查,因此该函数假定a是所有整数,依此类推。

最后,请注意 randi(IMAX,N,N) 返回的值在1:IMAX范围内,而不是您似乎声明的0:IMAX

关于Matlab快速邻域运算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16871203/

10-11 17:03