2013-09-03 20 views
5

私は正と負の値からなる行列を持っています。私はこれらのことをする必要があります。ピクセルの近傍を計算する最も簡単な方法

u(i,j)は、uのピクセルを示します。

  1. ゼロクロッシングピクセルを計算します。これらは、u(i-1,j)u(i+1,j)が反対の符号であるか、u(i,j-1)u(i,j+1)が反対の符号である場合、グリッドのピクセルです。
  2. 次に、これらのゼロクロスピクセルの周りの狭いバンドを計算する必要があります。狭帯域の幅は、各画素について(2r+1)X(2r+1)である。私はr=1を取っていますので、実際には、各ゼロクロスピクセルの8近傍のピクセルを取得しなければなりません。

私はこれをプログラムで行っています。下にそれを見てください。

%// calculate the zero crossing pixels 
front = isfront(u); 
%// calculate the narrow band of around the zero crossing pixels 
band = isband(u,front,1); 

私もisfrontisband機能を付加しています。

function front = isfront(phi) 
%// grab the size of phi 
[n, m] = size(phi); 

%// create an boolean matrix whose value at each pixel is 0 or 1 
%// depending on whether that pixel is a front point or not 
front = zeros(size(phi)); 

%// A piecewise(Segmentation) linear approximation to the front is contructed by 
%// checking each pixels neighbour. Do not check pixels on border. 
for i = 2 : n - 1; 
    for j = 2 : m - 1; 
    if (phi(i-1,j)*phi(i+1,j)<0) || (phi(i,j-1)*phi(i,j+1)<0) 
     front(i,j) = 100; 
    else 
     front(i,j) = 0; 
    end 
    end 
end 

function band = isband(phi, front, width) 
%// grab size of phi 
[m, n] = size(phi); 

%// width=r=1; 
width = 1; 

[x,y] = find(front==100); 

%// create an boolean matrix whose value at each pixel is 0 or 1 
%// depending on whether that pixel is a band point or not 
band = zeros(m, n); 

%// for each pixel in phi 
for ii = 1:m 
    for jj = 1:n 
    for k = 1:size(x,1) 
     if (ii==x(k)) && (jj==y(k)) 
      band(ii-1,jj-1) = 100; band(ii-1,jj) = 100; band(ii-1,jj+1) = 100; 
      band(ii ,jj-1) = 100; band(ii ,jj) = 100; band(ii,jj+1) = 100; 
      band(ii+1,jj-1) = 100; band(ii+1,jj) = 100; band(ii+1,jj+1) = 100; 
     end 
    end 
    end 
end 

出力は:,だけでなく、計算時間以下に示す:

Figure

%// Computation time 

%// for isfront function 
Elapsed time is 0.003413 seconds. 

%// for isband function 
Elapsed time is 0.026188 seconds. 

私は正しい答えを得るかのコードが、タスクのための計算を実行すると、私の好みにはあまりにも多いです。それを行うより良い方法はありますか?特にisbandの機能は?コードをさらに最適化するにはどうすればよいですか?

ありがとうございます。

+3

あなたは形態学的操作を考えがありますが、[ 'bwmorph'](http://www.mathworks.com/help/images/ref/bwmorph.html)言うの? –

+1

注意: 'isband'の右下の2つの隣接ピクセルへのアクセスは不正確です。あなたはおそらくコピーペーストし、-1を+1と+0に訂正するのを忘れたでしょう。 –

+0

@RodyOldenhuisコメントをいただきありがとうございます。うん、私はそれをコピーして貼り付けたので間違いだった。それを修正するために私の質問を編集しました。 – roni

答えて

5

EitanTの提案によれば、すでに少なくともあなたが望むことを行うのはbwmorphです。

あなたは何の画像処理ツールボックスへのアクセス権を持っていない、またはちょうどそれを自分で行う上で主張しない場合:

あなたはベクトル化さ

front = zeros(n,m); 

zero_crossers = ... 
    phi(1:end-2,2:end-1).*phi(3:end,2:end-1) < 0 | ... 
    phi(2:end-1,1:end-2).*phi(2:end-1,3:end) < 0; 

front([... 
        false(1,m) 
    false(n-2,1) zero_crossers false(n-2,1) 
        false(1,m)     ]... 
) = 100; 

isfrontでトリプルループを置き換えることができるとのことができます。この単一ループによってisbandを置き換えます。また

[n,m] = size(front); 
band = zeros(n,m); 
[x,y] = find(front); 
for ii = 1:numel(x) 
    band(... 
     max(x(ii)-width,1) : min(x(ii)+width,n),... 
     max(y(ii)-width,1) : min(y(ii)+width,m)) = 1; 
end 

、ミラノによって示唆されているように、あなたは画像を適用することができますdilati convolution経由で:さらに高速でなければなりません

kernel = ones(2*width+1);  
band = conv2(front, kernel); 
band = 100 * (band(width+1:end-width, width+1:end-width) > 0); 

そして、あなたはもちろん、他のいくつかのマイナーな最適化を持つことができます(isbandfindは、より高速などであるように、あなたは論理的な配列としてfrontを渡すことができ、引数としてphiを必要としません)。

+0

クイックインフォメーション私は75X79のサイズを持つ画像で時間を計ろうとしていましたが、私は自分の関数is_frontと関数is_frontの両方をタイムアウトしました。 結果は次のとおりです。run1:経過時間は0.003101秒です。 経過時間は0.004594秒です。 run2:経過時間は0.002801秒です。 経過時間は0.004535秒です。 – roni

+0

次に、4000X4000にイメージのサイズを変更しました。このタイミングの結果が得られます。 run1:経過時間は2.646254秒です。 経過時間は0.766821秒です。 run2:経過時間は2.853837秒です。 経過時間は0.737387秒です。 小さいアレイではコードが高速になり、大きなアレイではコードが遅くなるのはなぜですか?説明できますか ?ベクター化されたコードがもっと速く動くはずはありませんか? – roni

+0

function is_band同様に run1:my func:0.006310秒。 あなたの機能:0.004052秒。 run2:my func:0.005674秒。 あなたの機能:0.004003秒。 run3:my func:0.005919秒。 あなたの機能:0.003908秒。 – roni

1

r == 1だけに興味がある場合は、makelutと対応する関数bwloolupを参照してください。

[EDIT]

% Let u(i,j) denote the pixels of the matrix u. Calculate the zero crossing 
% pixels. These are the pixels in the grid if u(i-1,j) and u(i+1,j) are of 
% opposite signs or u(i,j-1) and u(i,j+1) are of opposite signs. 

% First, create a function which will us if a pixel is a zero crossing 
% pixel, given its 8 neighbors. 

% uSign = u>0; % Note - 0 is treated as negative here. 

% uSign is 3x3, we are evaluating the center pixel uSign(2,2) 
zcFun = @(uSign) (uSign(1,2)~=uSign(3,2)) || (uSign(2,1)~=uSign(2,3)); 

% Make a look up table which tells us what the output should be for the 2^9 
% = 512 possible patterns of 3x3 arrays with 1's and 0's. 
lut = makelut(zcFun,3); 

% Test image 
im = double(imread('pout.tif')); 
% Create positve and negative values 
im = im -mean(im(:)); 

% Apply lookup table 
imSign = im>0; 
imZC = bwlookup(imSign,lut); 

imshowpair(im, imZC); 
+0

あなたは私にどのように表示できますか?私は材料を見て、それは私には分かりません。私は形態学的方法についてはほとんど考えていません。それを適用する方法のヒントを教えてください。 – roni

関連する問題