2013-09-03 7 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의 기능은 무엇입니까? 코드를 어떻게 최적화 할 수 있습니까?

미리 감사드립니다. EitanT에 의해 제안

+3

당신이 생각 해 봤나 형태 학적 작업은 말 ['bwmorph'] (http://www.mathworks.com/help/images/ref/bwmorph.html)? –

+1

주의 : 'isband'의 오른쪽 아래에있는 두 개의 인접 픽셀에 대한 액세스가 잘못 코딩되었습니다. 당신은 아마도 복사 붙여 넣기, 그리고 -1을 +1 및 +0로 수정하는 것을 잊었을 것입니다. –

+0

@RodyOldenhuis 코멘트 주셔서 감사합니다. 그래, 내가 실수로 복사해서 붙여 넣었다. 수정하기 위해 내 질문을 수정했습니다. – roni

답변

5

, 이미 당신이 원하는 것을 적어도 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을 적용 할 수 있습니다

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

더 빨리해야한다 : convolution을합니다.

그리고 당신은 물론 다른 사소한 최적화를 할 수 있습니다 (isbandfind가 빠른 등이다 있도록 논리적 배열로 front를 전달할 수 있습니다, 인수로 phi을 필요로하지 않습니다). 당신이 R == 1 만 관심이 있다면

+0

빠른 정보 나는 75X79의 크기를 가진 나의 이미지로 시간을 정해려고 노력했다. 그리고 나는 나의 함수 is_front와 당신의 함수 is_front 둘다를 Timed했다. 결과는 다음과 같습니다. 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

마찬가지로 함수 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

makelut 및 해당 기능 bwloolup 봐.

[편집]

% 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

관련 문제