1

Matlabのフィルターバンクを使用して画像をフィルター処理する必要があります。私の最初の試みは、単純なforループを使用して、バンク内の各フィルターに対して「imfilter」関数を繰り返し呼び出すことでした。

アプリケーションではこのプロセスを何度も繰り返す必要があるため、できるだけ効率的にするためにこの手順を実行する必要があります。したがって、この操作をベクトル化してプロセスを高速化する方法はないかと思いました。物事を単純化するために、私のフィルターカーネルはすべて同じサイズ(9x9)です。

私が目指していることの例として、私のフィルターは9x9x32要素ブロックに設定されています。これは私の画像に適用する必要があります。画像をブロック(100x100x32など)に複製することを考えましたが、ループに頼らずに畳み込みなどの操作を適用する方法があるかどうかはわかりません。この問題に取り組む良い方法について誰かが提案を持っていますか?

4

2 に答える 2

2

スペースを事前に割り当てる以外に、正確な解決策に到達するためのより速い方法はありません。近似に問題がない場合は、32個のフィルターを少数のフィルター(たとえば8個)の線形結合のセットに分解できる可能性があります。たとえば、操縦可能なフィルターを参照してください。

http://people.csail.mit.edu/billf/papers/steerpaper91FreemanAdelson.pdf

編集:これは、画像にフィルターを適用するのに役立つツールです。

function FiltIm = ApplyFilterBank(im,filters)
%#function FiltIm = ApplyFilterBank(im,filters)
%#
%#assume im is a single layer image, and filters is a cell array

nFilt = length(filters);
maxsz = 0;
for i = 1:nFilt
  maxsz = max(maxsz,max(size(filters{i})));
end
FiltIm = zeros(size(im,1), size(im,2), nFilt);
im = padimage(im,maxsz,'symmetric');
for i = 1:nFilt
  FiltIm(:,:,i) = unpadimage(imfilter(im,filters{i}),maxsz);
end

function o = padimage(i,amnt,method)
%#function o = padimage(i,amnt,method)
%#
%#padarray which operates on only the first 2 dimensions of a 3 dimensional
%#image. (of arbitrary number of layers);
%#
%#String values for METHOD
%#        'circular'    Pads with circular repetion of elements.
%#        'replicate'   Repeats border elements of A.
%#        'symmetric'   Pads array with mirror reflections of itself. 
%#
%#if(amnt) is length 1, then pad all sides same amount
%#
%#if(amnt) is length 2, then pad y direction amnt(1), and x direction amnt(2)
%#
%#if(amnt) is length 4, then pad sides unequally with order LTRB, left top right bottom
if(nargin < 3)
   method = 'replicate';
end
if(length(amnt) == 1)
  o = zeros(size(i,1) + 2 * amnt, size(i,2) + 2* amnt, size(i,3));
  for n = 1:size(i,3)
    o(:,:,n) = padarray(i(:,:,n),[amnt,amnt],method,'both');
  end
end
if(length(amnt) == 2)
  o = zeros(size(i,1) + 2 * amnt(1), size(i,2) + 2* amnt(2), size(i,3));
  for n = 1:size(i,3)
    o(:,:,n) = padarray(i(:,:,n),amnt,method,'both');
  end
end
if(length(amnt) == 4)
  o = zeros(size(i,1) + amnt(2) + amnt(4), size(i,2) + amnt(1) + amnt(3), size(i,3));
  for n = 1:size(i,3)
    o(:,:,n) = padarray(padarray(i(:,:,n),[amnt(2), amnt(1)],method,'pre'),[amnt(4),     amnt(3)],method,'post');
  end
end

function o = unpadimage(i,amnt)
%#un does padimage
%#if length(amnt == 1), unpad equal on each side
%#if length(amnt == 2), first amnt is left right, second up down
%#if length(amnt == 4), then [left top right bottom];

switch(length(amnt))
case 1
  sx = size(i,2) - 2 * amnt;
  sy = size(i,1) - 2 * amnt;
  l = amnt + 1;
  r = size(i,2) - amnt;
  t = amnt + 1;
  b = size(i,1) - amnt;
case 2
  sx = size(i,2) - 2 * amnt(1);
  sy = size(i,1) - 2 * amnt(2);
  l = amnt(1) + 1;
  r = size(i,2) - amnt(1);
  t = amnt(2) + 1;
  b = size(i,1) - amnt(2);
case 4
  sx = size(i,2) - (amnt(1) + amnt(3));
  sy = size(i,1) - (amnt(2) + amnt(4));
  l = amnt(1) + 1;
  r = size(i,2) - amnt(3);
  t = amnt(2) + 1;
  b = size(i,1) - amnt(4);
otherwise
  error('illegal unpad amount\n');
end
if(any([sx,sy] < 1))
    fprintf('unpadimage newsize < 0, returning []\n');
    o = [];
    return;
end

o = zeros(sy, sx, size(i,3));
for n = 1:size(i,3)
  o(:,:,n) = i(t:b,l:r,n);
end
于 2011-06-14T20:10:49.753 に答える
0

新しい回答:colfilt()またはブロックフィルタリングスタイルを使用してください。Matlabは、画像を大きなマトリックスに変換できます。このマトリックスでは、9x9ピクセルの各領域が1つの列(81要素)になります。im2col()メソッドを使用して作成します。画像がNxMの場合、結果の行列は81 X(N-8)*(M-8)になります。

次に、すべてのフィルターを単一の行列に連結し(各フィルターは行です)、それらの巨大な行列を乗算できます。これにより、すべてのフィルターの結果が得られます。次に、結果マトリックスから32の結果画像を再構成する必要があります。col2im()メソッドを使用します。詳細については、「doccolfilt」と入力してください

このメソッドはmexファイルとほぼ同じ速度で動作し、「for」ループを必要としません。

古い答え:

フィルタの組み合わせに対して、異なる32の結果または単一の結果を取得しますか?それがサングルの結果である場合、簡単な方法があります。線形フィルター(畳み込みなど)を使用する場合は、フィルターを相互に適用します。最後に、結果のフィルターを画像に適用します。したがって、画像は1回だけ畳み込まれます。フィルタが対称(xおよびy方向)の場合、9x9フィルタを適用する代わりに、y方向に9x1を適用し、x方向に1x9を適用します。少し速く動作します。最後に、Mexファイルを使用してみることができます

于 2011-06-14T21:23:20.270 に答える