2

チェーンコードを実装していますが、小さな問題に遭遇しました。まず第一に私がすること:

境界上の特定のピクセルから開始し、これに従ってどの隣接ピクセルが存在するかを確認します。

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

ここで私は問題がありますが:

ここに画像の説明を入力してください

小さな赤い点は、アルゴリズムが開始する場所です。次に、最初の方向は2、1、0、0などです。

黄色の点をたどると、2つの点が隣り合って終了していることがわかります。これは、アルゴリズムが方向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番目のバージョンでは、アルゴリズムが以前にアクセスしたピクセルを使用していないことを確認しました。結果: ここに画像の説明を入力してください

ご覧のとおり、これは実用的な答えではありません。

編集2

@jonasの更新されたソリューションについて。すぐにExcelに入れて、わかりやすくしました。(1のピクセルはまだ検出されていません、ピクセルxはすでに検出されています)。

ここに画像の説明を入力してください

したがって、これは100%は機能しません。巨大なデータセットを操作する場合、すべての画像のエッジが2ピクセル幅であることを確認することはかなり不可能です。

4

2 に答える 2

2

アルゴリズムの問​​題は、訪問する「候補」ピクセルがオブジェクトの一部であるかどうかのみをチェックすることですが、ピクセルが境界の一部であることを確認するための追加のチェックは実行しません。これが、オブジェクトの内部を楽しく歩く理由です。

境界トレースの一般的なアルゴリズムは、ムーア近傍トレースアルゴリズムです。ウィキペディアのページに加えて、このページを見てください。このページでは、アルゴリズムの背後にある考え方について詳しく説明しています。

于 2012-10-15T08:22:01.877 に答える
1

これを修正する最も簡単な方法は、関数BWTRACEBOUNDARYを使用することです。

あなたの出発点(x,y)で、あなたは書くでしょう:

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

画像上にプロットされた結果は、次のようになります。

ここに画像の説明を入力してください

編集

を使用できない場合はbwtraceboundary、最初に境界ピクセルのみを取得する必要があります。

境界=Ibw-imerode(Ibw、ones(3));

これにより、オブジェクトの幅が2ピクセルを超えている限り、ほとんどすべての問題を回避できます。

于 2012-10-15T03:58:50.197 に答える