2012-10-02 11 views
6

私が現在開発中のこのアルゴリズムの名前があるかどうかはわかりません - 「近所の成長アルゴリズム」は適切な名前のように聞こえます。だから私の問題は何ですか?アルファ透明画像の周りにアウトラインやストロークを描画するアルゴリズム

アルファ透明画像の周りにストロークを描き、アウトラインを描きたいと思います。ストロークのサイズはユーザー定義可能でなければなりません。

私は0と1で塗りつぶされた配列を持っていますが、Game of Lifeのように配列の各項目をセルと見なします。 0のアイテムは空(透明ピクセル)、1のアイテムは第1世代セル(非透明ピクセル)、世代数は周囲のストロークのサイズによって定義されます。

0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 1 1 1 1 0 0 0 
0 0 0 1 1 1 1 0 0 0 
0 0 0 1 1 1 1 0 0 0 
0 0 0 1 1 1 1 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 

その後、私はものは、すべて0世代ムーアの隣人を囲むことによって、新しい世代を成長させたいと思います:

この例では、アルファ値に囲まれた四角形を描いています。これは、第二世代(1ピクセルでストローク)だ - これアレイは、次のように成長した後になります。

0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 2 2 2 2 2 2 0 0 
0 0 2 1 1 1 1 2 0 0 
0 0 2 1 1 1 1 2 0 0 
0 0 2 1 1 1 1 2 0 0 
0 0 2 1 1 1 1 2 0 0 
0 0 2 2 2 2 2 2 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 

第3および第4世代(3pxとストローク):これまでのところ

4 4 4 4 4 4 4 4 4 4 
4 3 3 3 3 3 3 3 3 4 
4 3 2 2 2 2 2 2 3 4 
4 3 2 1 1 1 1 2 3 4 
4 3 2 1 1 1 1 2 3 4 
4 3 2 1 1 1 1 2 3 4 
4 3 2 1 1 1 1 2 3 4 
4 3 2 2 2 2 2 2 3 4 
4 3 3 3 3 3 3 3 3 4 
4 4 4 4 4 4 4 4 4 4 

とても良いです。私はこの単純なタスクを次のコードスニペットで達成しています。

for (int gen = 1; gen <= 4; gen++) 
{ 
    for (int x = 1; x < arrayWidth - 1; x++) 
    { 
     for (int y = 1; y < arrayHeight - 1; y++) 
     { 
      // See if this cell is in the current generation. 
      if (_generation[x + arrayWidth * y] == gen) 
      { 
       // Generate next generation. 
       for (int i = x - 1; i <= x + 1; i++) 
       { 
        for (int j = y - 1; j <= y + 1; j++) 
        { 
         if (_generation[i + arrayWidth * j] == 0 || _generation[i + arrayWidth * j] > gen) 
         { 
          _generation[i + arrayWidth * j] = gen + 1; 
         } 
        } 
       } 
      } 
     } 
    } 
} 

このアプローチは、たとえば矩形のような単純な形状に対しては完全に機能します。しかし、私はどのようにこれを楕円で行うことができますか?すぐに我々は、細胞内階段パターンのようなものを持っているとして、私は厄介な結果を得ている:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 1 1 1 1 0 0 0 0 0 
0 0 0 0 1 1 1 1 1 1 0 0 0 0 
0 0 0 1 1 1 1 1 1 1 1 0 0 0 
0 0 1 1 1 1 1 1 1 1 1 1 0 0 
0 0 1 1 1 1 1 1 1 1 1 1 0 0 
0 0 1 1 1 1 1 1 1 1 1 1 0 0 
0 0 1 1 1 1 1 1 1 1 1 1 0 0 
0 0 1 1 1 1 1 1 1 1 1 1 0 0 
0 0 0 1 1 1 1 1 1 1 1 0 0 0 
0 0 0 0 1 1 1 1 1 1 0 0 0 0 
0 0 0 0 0 1 1 1 1 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 

0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 2 2 2 2 2 2 0 0 0 0 
0 0 0 2 2 1 1 1 1 2 2 0 0 0 
0 0 2 2 1 1 1 1 1 1 2 2 0 0 
0 2 2 1 1 1 1 1 1 1 1 2 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 2 1 1 1 1 1 1 1 1 2 0 0 
0 0 2 2 1 1 1 1 1 1 2 2 0 0 
0 0 0 2 2 1 1 1 1 2 2 0 0 0 
0 0 0 0 2 2 2 2 2 2 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 

0 0 0 3 3 3 3 3 3 3 3 0 0 0 
0 0 3 3 2 2 2 2 2 2 3 3 0 0 
0 3 3 2 2 1 1 1 1 2 2 3 3 0 
3 3 2 2 1 1 1 1 1 1 2 2 3 3 
3 2 2 1 1 1 1 1 1 1 1 2 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 2 1 1 1 1 1 1 1 1 2 2 3 
3 3 2 2 1 1 1 1 1 1 2 2 3 3 
0 3 3 2 2 1 1 1 1 2 2 3 3 0 
0 0 3 3 2 2 2 2 2 2 3 3 0 0 
0 0 0 3 3 3 3 3 3 3 3 0 0 0 

楕円にこのアルゴリズムを適用すると、輪郭がこの問題のためちょっと奇妙に見える(左:アルゴリズムの結果を、右:要求された結果は):

1 0 0 0 0 0 0 1 
0 1 0 0 0 0 1 0 
0 0 1 0 0 1 0 0 
0 0 0 1 1 0 0 0 

ここでの問題は、私はこの「階段」パターンを持つたびに発生したもの2つの2と3 3重複ブロックを持って望んでいないということです 私はそれらの重複セルブロックをフィルタリングするための多くの方法を試してみたが、私は解決するための簡単で一般的な解決策を見つけることができません

0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 2 2 2 2 0 0 0 0 0 
0 0 0 0 2 1 1 1 1 2 0 0 0 0 
0 0 0 2 1 1 1 1 1 1 2 0 0 0 
0 0 2 1 1 1 1 1 1 1 1 2 0 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 2 1 1 1 1 1 1 1 1 1 1 2 0 
0 0 2 1 1 1 1 1 1 1 1 2 0 0 
0 0 0 2 1 1 1 1 1 1 2 0 0 0 
0 0 0 0 2 1 1 1 1 2 0 0 0 0 
0 0 0 0 0 2 2 2 2 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 

0 0 0 0 0 3 3 3 3 0 0 0 0 0 
0 0 0 0 3 2 2 2 2 2 3 0 0 0 
0 0 0 3 2 1 1 1 1 2 3 0 0 0 
0 0 3 2 1 1 1 1 1 1 2 3 0 0 
0 3 2 1 1 1 1 1 1 1 1 2 3 0 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
3 2 1 1 1 1 1 1 1 1 1 1 2 3 
0 3 2 1 1 1 1 1 1 1 1 2 3 0 
0 0 3 2 1 1 1 1 1 1 2 3 0 0 
0 0 0 3 2 1 1 1 1 2 3 0 0 0 
0 0 0 3 2 2 2 2 2 2 3 0 0 0 
0 0 0 0 3 3 3 3 3 3 0 0 0 0 

私は上記の2番目と3番目の世代の計算をしたいが、このようになります問題。

私はPhotoshopやPaint.NETから得たような筆跡/輪郭を得る方法はありますか?

ありがとうございます!

乾杯 P

+2

私はあなたが適切な '構造化element'と'形態学的dilation'で進歩を遂げるかもしれないと思います。あなたが答えを待つ間、私は詳細を説明する時間がありません。http://en.wikipedia.org/wiki/Mathematical_モルフォロジー –

+1

あなたの質問は誰にとっても一例になるはずです。質問 " –

答えて

5

適切な名前がdilationで、形態学的操作をチェックしてください。あなたは円の要素で膨張を試みる必要があります、これはあなたに要求された結果を与えるでしょう。ここで

は、それがどのように行われるかを示してMATLABコードです:

im = imcircle(70); 
im = padarray(im,[20,20]); 
figure;imshow(im); 
im2 = imdilate(im,strel('disk',8)); 
figure;imshow(im2); 

enter image description here

+2

これはまさに私が探しているものです!ありがとう!このアルゴリズムの名前を知っているともっと簡単に研究ができます;) 非常に有用なリンク:http://homepages.inf.ed.ac.uk/rbf/HIPR2/dilate.htm また、Matlabのリファレンス適切なカーネル:http://www.mathworks.de/de/help/images/ref/strel.html – barnacleboy

+1

このコンセプトは、160行以上の複雑なスクリプトを約20行の読みやすい行に減らすのに役立ちました。 Googleはこの素晴らしいページに私を連れて来ました:https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html – itnAAnti

関連する問題