5

私は問題があります。0 から 5 までの整数値を持つ行列Aがあります。たとえば、次のようになります。

x=randi(5,10,10)

ここで、サイズ 3x3 のフィルターを呼び出したいと思います。これにより、最も一般的な値が得られます。

私は2つの解決策を試しました:

fun = @(z) mode(z(:));
y1 = nlfilter(x,[3 3],fun);

これには非常に時間がかかります...

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

これも時間がかかります。非常に大きなマトリックスがいくつかあり、両方のソリューションに時間がかかります。より速い方法はありますか?

4

2 に答える 2

3

使用する優れた提案については、@Florisに+1してくださいhist。とても速いです。ただし、もう少しうまくいくことができます。histに基づいておりhistc、代わりに使用できます。histcコンパイルされた関数です。つまり、Matlab で記述されていません。そのため、ソリューションははるかに高速です。

これは、@Florisが行ったことを一般化し(そのソリューションは、目的の行列ではなくベクトルを返します)、 and で行っていることを達成しようとする小さな関数nlfilterですcolfilt。入力が特定の次元を持つ必要はなくim2col、データを効率的に再配置するために使用されます。実際、最初の 3 行と への呼び出しは、あなたの場合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 倍以上高速です。で置き換えるhisthistc、速度が 2 倍になります。aもちろん、入力チェックは行われないため、関数はそれがすべて整数などであると想定します。

最後に、あなたが述べているようにではなくrandi(IMAX,N,N)、範囲内の値を返すことに注意してください。1:IMAX0:IMAX

于 2013-06-01T21:13:54.473 に答える