2017-02-12 4 views
0

Я вычисляю кратчайшее расстояние от каждого пикселя переднего плана до фонового. Я попробовал несколько вариантов, но не работал, как я думал (есть встроенная функция Matlab «bwdist» дает расстояние между этим пикселем и ближайшим ненулевым пикселем. Но я создаю свой собственный, чтобы дать расстояние между 1 -пиксель и ближайший нулевой пиксель.) Вот одна из версий, которые у меня есть.Рассчитайте кратчайшее расстояние каждого 1-пикселя до любого нулевого пикселя в Matlab

Say «Im» является исходная матрица с 10x10 пикселей (Он был случайно создан. Действительная матрица гораздо больше, чем это.)

Im = 
0  0  0  0  0  0  0  0  0 
0  0  0  1  1  1  1  0  0 
0  0  0  1  1  1  1  1  0 
0  0  1  0  1  1  1  1  1 
0  0  1  1  1  1  1  1  1 
0  0  0  1  1  1  1  1  0 
0  0  0  0  1  1  1  1  0 
0  0  0  0  1  1  1  1  0 
0  0  0  0  0  1  1  0  0 
0  0  0  0  0  0  0  0  0 

DT = Im;%create a copy matrix of Im 
for i = 1: size(DT,1) 
    for j = 1: size(DT,2) 
     %I want to select all pixels with a distance of 1 to current pixel 
     %(i,j), e.g. (i-1,j), (i,j-1), (i+1,j),(i,j+1) would be the case for Euclidean 
     %distance. The large size of matrix (say 512x512) also makes it very inefficient 
     %use four for-loops to find these pixels with distance of 1 to current pixel. So 
     %I use (i-1,j) etc instead of using 
     %sqrt(sum(bsxfun(@minus,[u v],[i j]).^2,2)) 
     %to find out all (u,v)s with distance of 1 to current pixel (i,j). 
     %But I do believe there are thousands smart ways to make this work efficiently. 

     if (Im(i-1,j) == 0 || Im(i,j-1) == 0 || Im(i,j+1) == 0 || Im(i+1,j) == 0)%I want to mark all pixels with 0 to remain as 0 
      DT(i-1,j) = Im(i-1,j); 
      DT(i,j-1) = Im(i-1,j); 
      DT(i,j+1) = Im(i,j+1); 
      DT(i+1,j) = Im(i+1,j); 

     else 
     %I want to update the visited pixels with the minimum value 
     %of calculated distances. Apparently, here is my problem. The code is not correct. 

      DT(i-1,j) = min(DT(i-1,j),Im(i-1,j) + DT(i,j)); 
      DT(i,j-1) = min(DT(i,j-1),Im(i,j-1) + DT(i,j)); 
      DT(i,j+1) = Im(i,j+1) + DT(i,j)); 
      DT(i+1,j) = Im(i+1,j) + DT(i,j); 
     end  
    end 
end 

Большое спасибо за любую помощь заранее!

+0

Как насчет 'bwdist (1-Im)'? – aksadv

+0

Он работает с использованием bwdist (~ Im). Но я играю, чтобы увидеть, могут ли вышеуказанные коды работать одинаково. – Orangeblue

ответ

0

Существует встроенный в функции Matlab bwdist, которая дает расстояние между пикселем и ближайшим ненулевым пикселем. Но я создаю свой собственный , чтобы дать расстояние между 1 пикселем и ближайшим нулем пикселей.

Я думаю, что вам не нужно создавать свою собственную функцию, потому что вы все равно можете использовать bwdist за то, что вы пытаетесь сделать. Вы можете использовать logical NOT ~, чтобы инвертировать изображение, а затем использовать bwdist, как показано в следующем примере:

% Binary image. 
Im = [ 
    0 0 0 
    0 1 0 
    0 0 0]; 

% Distance transform of binary image. 
D1 = bwdist(Im) 

% Distance transform of inverted binary image. 
D2 = bwdist(~Im) 

Выходы:

D1 = 
    1.4142 1.0000 1.4142 
    1.0000   0 1.0000 
    1.4142 1.0000 1.4142 
D2 = 
    0  0  0 
    0  1  0 
    0  0  0 
+0

Приятная находка! Но мне все еще интересно, сделаю ли я это с основной идеей, которую я дал в вопросе, как заставить ее работать без bwdist? Цените. – Orangeblue

0

я понял это сам. Вот мой код:

DT = Im;%create a copy matrix of Im 
for i = 1: size(DT,1) 
    for j = 1: size(DT,2) 
      %I want to select all pixels with a distance of 1 to current pixel 
     %(i,j), e.g. (i-1,j), (i,j-1), (i+1,j),(i,j+1) would be the case for Euclidean 
     %distance. The large size of matrix (say 512x512) also makes it very inefficient 
     %use four for-loops to find these pixels with distance of 1 to current pixel. So 
     %I use (i-1,j) etc instead of using 
     %sqrt(sum(bsxfun(@minus,[u v],[i j]).^2,2)) 
     %to find out all (u,v)s with distance of 1 to current pixel (i,j). 
     %But I do believe there are thousands smart ways to make this work efficiently. 

     if (Im(i-1,j) == 0 || Im(i,j-1) == 0 || Im(i,j+1) == 0 || Im(i+1,j) == 0)%I want to mark all pixels with 0 to remain as 0 
      DT(i-1,j) = Im(i-1,j); 
      DT(i,j-1) = Im(i-1,j); 
      DT(i,j+1) = Im(i,j+1); 
      DT(i+1,j) = Im(i+1,j); 

     else 
     %I want to update the visited pixels with the minimum value 
     %of calculated distances. Apparently, here is my problem. The code is not correct. 

      DT(i-1,j) = min(DT(i-1,j),Im(i-1,j) + DT(i,j)); 
      DT(i,j-1) = min(DT(i,j-1),Im(i,j-1) + DT(i,j)); 
      DT(i,j+1) = min(DT(i,j+1),Im(i,j+1) + DT(i,j)); 
      DT(i+1,j) = Im(i+1,j) + DT(i,j); 
     end  
    end 
end 

Кроме того, цикл должен просканировать снизу вверх, чтобы заменить DT с минимальным значением, если есть.

Смежные вопросы