2

これはもう少し一般的な質問ですが、MATLAB の im2col 関数の説明を何度読んでも完全には理解できません。MATLAB はネストされた for ループがひどいので、計算効率のために必要です。これが私がやろうとしていることですが、ネストされたforループを使用しています:

 [TRIMMED]=TM_FILTER(IMAGE, FILTER_SIZE, PERCENT)
    Takes a 2-D array and returns the array, filtered with a
    square trimed mean filter with length/width equal to FILTER_SIZE and percent equal to PERCENT.

    %}
    function [trimmed]=tm_filter(image, filter_size, percent)
    if rem(filter_size, 2)==0                            %make sure filter has a center pixel
        error('filter size must be odd numbered');       %error and return if number is odd
        return 
    end
    if percent > 100 || percent < 0
        error('Percentage must be ? [0, 100]');
        return
    end

    [rows, columns]=size(image);              %figure out pixels needed
    n=(filter_size-1)/2;                      %n is pixel distance from center pixel to boundaries  
    padded=(padarray(image, [n,n],128));      %padding on boundaries so center pixel always has neighborhood

for i=1+n:rows                            %rows from first non-padded entry to last nonpadded entry
    for j=1+n:columns                     %colums from first non-padded entry to last nonpadded entry
    subimage=padded(i-n:i+n,j-n:j+n);     %neighborhood same size as filter
    average=trimmean(trimmean(subimage, percent), percent);         %computes trimmed mean of neighborhood as trimmed mean of vector of trimmed means
    trimmed(i-n, j-n)=average;         %stores averaged pixel in new array
    end
end
trimmed=uint8(trimmed);             %converts image to gray levels from 0-255
4

2 に答える 2

3

必要なコードは次のとおりです。ネストされたループ全体が単一のステートメントに置き換えられていることに注意してください。

 [TRIMMED]=TM_FILTER(IMAGE, FILTER_SIZE, PERCENT)
    Takes a 2-D array and returns the array, filtered with a
    square trimed mean filter with length/width equal to FILTER_SIZE and percent equal to PERCENT.

    %}
    function [trimmed]=tm_filter(image, filter_size, percent)
    if rem(filter_size, 2)==0                            %make sure filter has a center pixel
        error('filter size must be odd numbered');       %error and return if number is odd
        return 
    end
    if percent > 100 || percent < 0
        error('Percentage must be ? [0, 100]');
        return
    end

    trimmed = (uint8)trimmean(im2col(image, filter_size), percent);

説明:

このim2col関数は、の各領域をfilter_size列に変換します。関数trimmeanは、1 回の操作で各領域 (列) を操作できます。各形状を順番に抽出するよりもはるかに効率的です。また、これには1回の適用のみが必要であることに注意trimmeanしてください-元の場合、最初に列でそれを実行し、次に行で再度実行します。これにより、実際には意図したよりも深刻なトリミングが発生します(最初に50%を除外し、次に50%を除外します)繰り返しますが、75% を除外しているように感じます. 正確には正しくありませんが、私の主張は理解できます)。また、フィルターが非線形であるため、操作の順序を変更すると (行、次に列対列、次に行)、結果が変わることがわかります。

例えば

im = reshape(1:9, [3 3]);
disp(im2col(im,[2 2])

結果は

1  2  4  5
2  3  5  6
4  5  7  8
5  6  8  9

この行列から 2x2 の 4 つの可能なブロックのそれぞれを取得したため:

1  4  7
2  5  8
3  6  9

そしてそれらを列に変えました

注 - この手法 (パディングされていない画像に適用) を使用すると、エッジのピクセルがいくつか失われます。メソッドはパディングを追加して、すべてのピクセル (端にあるものも含む) が完全な近傍を持つようにしました。そのため、フィルターは元のサイズと同じサイズの画像を返します (ただし、パディング/フィルタリングの効果がどうなるかは明確ではありません)。余白の近く、特に角に注意してください: ほぼ 75% のピクセルが 128 に固定されており、それが角での動作を支配する可能性があります)。

于 2013-06-20T18:43:35.183 に答える