Matlab 链码无限循环

Matlab 链码无限循环,matlab,image-processing,Matlab,Image Processing,我正在实现链式代码,我偶然发现了一个小问题。首先,我要做的是: 我从边界上的某个像素开始,然后检查哪个相邻像素出现: 3 2 1 \ | / 4-- --0 / | \ 5 6 7 虽然我有一个问题: 小红点是算法开始的地方。然后第一个方向是2然后是1然后是0然后是0等等 如果你沿着黄点走,你会看到它在两个相邻的点处结束。这就是算法朝着方向4前进的地方(因为在方向0、1、2或3没有值为1的像素)。虽然在下一步它会检查方向0(这始终是第一个开始的方向)。。。当然,它是存在的,因为它

我正在实现链式代码,我偶然发现了一个小问题。首先,我要做的是:

我从边界上的某个像素开始,然后检查哪个相邻像素出现:

3  2  1
 \ | /
4-- --0
 / | \
5  6  7
虽然我有一个问题:

小红点是算法开始的地方。然后第一个方向是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
在此图像上:

如果你想自己试试的话

编辑:

正如评论中所建议的,在我的第二个版本中,我确保算法没有使用以前访问过的像素。结果是:

正如你所见,这不是一个有效的答案

编辑2

关于@jonas的更新解决方案。我很快就把它放进了excel,这样更容易理解。(尚未找到带1的像素,已找到像素x)


因此,这并不能100%起作用,在处理大型数据集时,很难确保每张图片的边缘宽度为2像素。

解决这一问题的最简单方法是使用该函数

用你的起点
(x,y)
,你会写:

B = bwtraceboundary(Ibw,[x,y],'N');
绘制在图像上的结果如下所示:

编辑

如果无法使用
bwtraceboundary
,则应首先仅获取边界像素:

边界=Ibw-imerode(Ibw,1(3))


只要对象的宽度大于两个像素,这几乎可以避免所有问题。

算法的问题在于,它只检查要访问的“候选”像素是否是对象的一部分,而不执行其他检查以确保像素是边界的一部分。这就是为什么它会愉快地穿过对象的内部


一种流行的边界跟踪算法是摩尔邻域跟踪算法。除此之外,请看一看,它更详细地解释了算法背后的思想。

可能会标记已访问的节点,并且从不访问它们两次?深度优先搜索中的某事物。你尽可能深入,然后后退一步,沿着另一条似乎可行的路径走。我注意到我是从北方开始的,而不是从东方开始的。我想没关系,我不能用这个。我正在尝试快速原型算法,这样我就可以看到它是否适用于我的图像。然后我想用java实现它。我不知道它是如何工作的,也不知道我的VersionTX更新有什么问题,但是正如你所说的,当它的宽度超过2像素时仍然存在问题。为了让其他人理解这一点,我在edit2下的问题中添加了这个问题。