我有个问题。我有一个矩阵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/