2012-10-14 4 views
2

Я реализую код цепи, и я наткнулся на небольшую проблему. Прежде всего то, что я делаю:Цепочный код бесконечный цикл

Я начинаю в определенном пикселе на моей границе, а затем проверить, который соседний пиксель присутствует acoriding к этому:

3 2 1 
\ |/
4-- --0 
/| \ 
5 6 7 

Хотя здесь у меня есть проблема:

enter image description here

Маленькая красная точка, где начинается алгоритм. то первое направление равно 2, затем 1, затем 0, затем 0 и т. д.

Если вы следуете желтым точкам, вы увидите, что они заканчиваются в двух точках рядом друг с другом. Именно здесь алгоритм пошел в направлении 4 (поскольку в направлении 0,1,2 или 3 не было пикселя со значением 1). Хотя на следующем шаге он проверяет направление 0 (которое всегда является первым направлением для начала) ... и, конечно, оно существует, так как оно является предыдущим и будет правильным. Здесь он застревает в бесконечном цикле (слева направо и справа налево).

Вопрос теперь, как я могу это исправить?

код, который я использую:

% Implementation of tangent angle function (chain code) 

clear 
clc 

directions = [ 1, 0 
       1,-1 
       0,-1 
       -1,-1 
       -1, 0 
       -1, 1 
       0, 1 
       1, 1] 

I = imread('./IMAGES/1/M_201005_1_0001.pgm'); 
Ibw = im2bw(I,0.15); % This is also by setting all the pixels with intesity lower than 17 to 0; 


tanAngFunc ={}; 

[row,col] = find(Ibw); 

y = col(find(max(row)==row)) 
x = max(row) 

imshow(I) 
hold on; 
plot(y,x,'r.','MarkerSize',1) 
hold on 

l=1; 

    not_done = true; 
    while not_done 
    if l== 36 
     'test' 
    end 



     % Right (0) 
     if Ibw(x+directions(1,2),y+directions(1,1)) ~=0 

      tanAngFunc{l} = 0; 
      x= x+directions(1,2); 
      y= y+directions(1,1); 

     % Above right(1) 
     elseif Ibw(x+directions(2,2),y+directions(2,1)) ~=0 
      tanAngFunc{l} = 2; 
      x= x+directions(2,2); 
      y= y+directions(2,1); 

     % Above (2) 
     elseif Ibw(x+directions(3,2),y+directions(3,1)) ~=0 
      tanAngFunc{l} = 2; 
      x= x+directions(3,2); 
      y= y+directions(3,1); 

     % Above left (3) 
     elseif Ibw(x+directions(4,2),y+directions(4,1)) ~=0 
      tanAngFunc{l} = 2; 
      x= x+directions(4,2); 
      y= y+directions(4,1); 

     % Left (4) 
     elseif Ibw(x+directions(5,2),y+directions(5,1)) ~=0 
      tanAngFunc{l} = 2; 
      x= x+directions(5,2); 
      y= y+directions(5,1); 

     % Bottom left (5) 
     elseif Ibw(x+directions(6,2),y+directions(6,1)) ~=0 
      tanAngFunc{l} = 2; 
      x= x+directions(6,2); 
      y= y+directions(6,1); 

     % Bottom (6) 
     elseif Ibw(x+directions(7,2),y+directions(7,1)) ~=0 
      tanAngFunc{l} = 2; 
      x= x+directions(7,2); 
      y= y+directions(7,1); 

     % Bottom right (7) 
     elseif Ibw(x+directions(8,2),y+directions(8,1)) ~=0 
      tanAngFunc{l} = 3; 
      x= x+directions(8,2); 
      y= y+directions(8,1); 
     end 


     plot(y,x,'y.','MarkerSize',3) 
     hold on 

     pause(1) 
     l = l + 1; 





    not_done = (x ~= col(find(max(row)==row)) && y ~= max(row)); 
    end 

На этой фотографии: enter image description here

В случае, если вы хотите попробовать это сами

Edit:

Как было предложено в комментариях. В моей второй версии я убедился, что алгоритм не использовал pr очень посещаемые пиксели. Результат: enter image description here

Как вы можете видеть, это не рабочий ответ.

Edit 2

Что касается обновленного решения @jonas. Я быстро положил его в excel, так что это легче понять. (пиксель с 1 еще не найден, пиксель x уже найден).

enter image description here

Так это не работает на 100%, это скорее невозможно, чтобы убедиться, край каждой картины 2 пикселя в ширину при работе с огромным набором данных.

+1

Возможно, отметили посещенные узлы и не посещают их дважды? STH. в строке поиска по глубине. Вы заходите так глубоко, как можете, тогда вы делаете шаг назад и следуете по другому правдоподобному пути. – angainor

ответ

2

Проблема с вашим алгоритмом заключается в том, что он проверяет, является ли пиксель «кандидат» для посещения частью объекта, но не выполняет дополнительных проверок, чтобы убедиться, что пиксель является частью границы. Вот почему он будет счастливо ходить внутри объекта.

Популярным алгоритмом трассировки границ является алгоритм отслеживания окрестности Мура. В дополнение к Wikipedia page взгляните на this page, в котором более подробно объясняется идея алгоритма.

1

Самый простой способ исправить это - использовать функцию BWTRACEBOUNDARY.

С вашей отправной точкой (x,y), можно было бы написать:

B = bwtraceboundary(Ibw,[x,y],'N'); 

и результат, построенные на изображение, выглядит следующим образом:

enter image description here

EDIT

Если вы не можете использовать bwtraceboundary, сначала e только пограничные пикселы:

border = Ibw - imerode (Ibw, ones (3));

Это позволит избежать почти всех проблем, если ваш объект шире двух пикселей.

+0

Только что заметил, что я начал на север, а не на восток. Я предполагаю, что это не имеет значения. – Jonas

+0

Я не могу использовать это. Я пытаюсь быстро прототипировать алгоритм, чтобы я мог видеть, работает ли оно на моих изображениях. Затем я хочу реализовать его в java. С этим я не знаю, как это работает, или что не так с моей версией – Ojtwist

+0

@Ojtwist: О, я понимаю. См. Мое редактирование. – Jonas

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