0

RGB 画像マトリックスがあり、それにいくつかの空間フィルターを適用したいとします。一般に、要素ごとの操作を適用したいと考えています (これは大学の課題であり、画像処理ツールボックスで利用可能な組み込み関数を使用することは許可されていないことに注意してください)。フィルターを関数として記述し、bsxfunこれらの関数を画像に適用することにしました。

簡単な例は次のとおり
です。画像のすべてのグレー レベルに 50 を追加し、200 を超えるすべてのグレー レベルを 200 に置き換えたいとします。これが私のコードです。

a='C:\Users\sepideh\Desktop\IP_abadpour\S45C-113050518040.jpg';  
b=imread(a);  
b(:,:,1)=b(:,:,1)+50;  
b(:,:,2)=b(:,:,2)+50;  
b(:,:,3)=b(:,:,3)+50;  
c=reshape(b,[],1);  
d=bsxfun(@test,c,200);

testは次の形式の関数です。

function Out = test(in,a)  
   if in>a
      in=200;
   end
   Out = in;
end  

このコードは機能しません。2 行目の "in > a" は 0 と 1 を含む行列 (すべての要素が 1 ではなく、1 であってはならないことを意味します) であるため、デバッガーはifステートメントに分岐しません。

この関数の書き方と、パフォーマンスや実行速度に影響を与えずに空間解析とフーリエ解析を画像に適用する方法を教えてもらえますか?

4

2 に答える 2

1

したがって、投稿した例では、matlab のほとんどの演算子がネイティブに行列で機能するという事実を利用できます。

b=imread(a);
c = a + 50;
c(c > 200) = 200;

それはそれと同じくらい簡単です。

フィルタリングについては、許可があればconv2関数を見てみたいと思います。周波数ドメインに変換せずに、この方法で空間フィルタリングを行うことができます (周波数ドメインでのフィルターの乗算は、空間ドメインでの畳み込みと同じであることを思い出してください)。たとえば、基本的なローパス フィルターは次のようになります。

lpf = ones(5)./25;
c(:,:,1) = conv2(b(:,:,1), lpf);
c(:,:,2) = conv2(b(:,:,2), lpf);
c(:,:,3) = conv2(b(:,:,3), lpf);
于 2013-06-24T09:42:29.030 に答える
1

以下にいくつかの提案を示します。

  1. まず、RGB マトリックスの各レイヤーに個別に 50 を追加する必要はありません。あなたはただ行うことができます:

    b = b + 50;
    
  2. bに渡す前に形状を変更するのはなぜbsxfunですか? の出力のサイズはbsxfun画像のサイズと同じです。ここで何かを再形成する必要はありません。

  3. あなたの機能に関して、次の状態の公式ドキュメントにtest注意してください。bsxfun

    形式のバイナリ要素単位の関数は、任意の等しいサイズの配列をC = fun(A,B)受け入れ、同じサイズの出力を返します。出力配列の各要素は、andの対応する要素のみに対する操作の結果です。またはがスカラーの場合、他の入力配列のすべての要素にスカラーを適用した結果となるように、スカラー拡張もサポートする必要があります。ABCABfunABC

    したがってbsxfun、シングルトン展開を実行し、その 2 つの入力配列を同じサイズに「膨張」させてから、指定された関数を膨張させた配列に適用します。要素ごとの関数funは、実際には、スカラーではなく配列に対して機能します。ここで採用しても実際の利益は見られませんbsxfun

    つまり、 Danの提案に示されているようにコードを単純化するか、関数として実装できます。

    function out = test(in, a);
        out = in;
        out(in > a) = a;
    

    200 の代わりに値 210 を使用していた場合、すべてのグレー レベルも 210 に制限したいのでa、ハードコードされた値 200 の代わりに実際に使用する必要があると思います。関数を次のように書くこともできます。それで:

    function out = test(in, a)
        out = min(in, a);
    

    次に、次のように呼び出します。

    d = test(b, 200);
    

    より複雑な の代わりにd = bsxfun(@test, b, 200)

    別の代替手段は、次を使用することarrayfunです。

    d = arrayfun(@(x)test(x, 200), a);
    

    また

    d = arrayfun(@test, a, 200 * ones(size(a)));
    

    これは要素ごとにarrayfun適用され、関数はスカラーのみを操作する必要があります。ただし、ベクトル化された操作は言うまでもなく、通常はループよりも低速で実行されます。testtestarrayfun

  4. 空間分析については、Danconv2が提案したように確認してください (または、練習のために独自の 2-D 畳み込みを実装してください)。フーリエ解析の場合、周波数領域でおよび関数を使用することを検討してください。fft2ifft2

お役に立てれば!

于 2013-06-24T09:53:45.677 に答える