アプリ版:「スタンプのみでお礼する」機能のリリースについて

細線化のプログラム
C#で細線化のプログラムを作成してみましたがうまくいきません。
http://imagingsolution.blog107.fc2.com/blog-entr … を参考に作成しました。
うまくいかないところは、一部に縦線がいくつも残ってしますところです。
ソース
static Bitmap Shape(Bitmap bmp) {

int Flag = 0;
//初期化
for (int j = 0; j < bmp.Height ; j++)
{
for (int i = 0; i < bmp.Width ; i++)
{
if (bmp.GetPixel(i, j).R != 255) {
bmp.SetPixel(i, j, Color.FromArgb(0, 0, 0));
}
}
}
while(true){
//パターン1
for (int i = 1; i < bmp.Width - 1; i++)
{
for (int j = 1; j < bmp.Height - 1; j++)
{
if (bmp.GetPixel(i, j).R == 255)
{
//除去しないパターン
if (( 略 ))
{
//セーフ
}
else if ((略)){
//セーフ
}
//除去するパターン
else if ((bmp.GetPixel(i + 1, j).R != 255) || (bmp.GetPixel(i, j - 1).R != 255))
{
//黒にする
bmp.SetPixel(i, j, Color.FromArgb(0, 0, 0));
Flag++;
}
}
}
}
// MessageBox.Show(Flag.ToString());
//終了
if (Flag == 0)
return bmp;
Flag = 0;

/*パターン2も同じようにする*/

という感じでプログラムを組んでいます。

画像は失敗例です。アドバイスをお願いします

「細線化のプログラム」の質問画像

A 回答 (6件)

汚いフローですが書いてみました


※ ワードで書いたのでフローというよりは単純な流れ図みたいになってますが
  イメージだけ伝われば良いのでご愛嬌ということで

添付のようなフローで上手く動くのではないかと思います
「細線化のプログラム」の回答画像6
    • good
    • 0

補足です。



同一座標と言っていた部分が気になったので。

処理的にはこんな感じです。
while {
  for ()
  {
    for ()
    {
      //パターン1の除去
    }
  }

  if (パターン1で除去しなかったら終了)

  for ()
  {
    for ()
    {
      //パターン2の除去
    }
  }

  if (パターン2で除去しなかったら終了)

}

という具合です。
なので、1画面分ごとにパターン1の除去、パターン2の除去を繰り返します。

それでも、縦の線は残るような気もしますが、除去する/しないのパターンが間違えていないか?確認してみて下さい。
    • good
    • 0

koi1234さんがパターン1、パターン2を交互に繰り返すと言っていますが、それが正解です。


細線化では、ほぼ線の中心付近を1画素の線として残すように処理をしていきますが、パターン1では、線の右、上の方向から線を細くし、パターン2では線の左、下の方向から線を細くする処理を行っています。
そこで、今回の失敗例のプログラムを見ると、パターン1を繰り返してから、パターン2の繰り返しを行っているので、失敗例の線の位置は、もともとの線の位置の左下に偏っていませんか?
    • good
    • 0

これ、同時に置き換えないとだめだと思うんですが。



bmp0[bmp.Width][bmp.Height]
みたいなものを用意しておいて全部0にしておいて

//黒にする
bmp0[j][i]=1 ;
Flag++;

などとして、0にする箇所を記録しておいて

for (int i = 1; i < bmp.Width - 1; i++)
{
for (int j = 1; j < bmp.Height - 1; j++)
{
if ( bmp[i][j] != 0 ) {
bmp.SetPixel(i, j, Color.FromArgb(0, 0, 0));
}
}
}

と、する、といったことが必要ではないんでしょうか
    • good
    • 0

文書の為意味が上手く伝わっていないようです



まずフローチャートに関してですが画面全体に対しての
フローチャートを描いているのではなく
1座標に対してのフローチャートが描かれています
(フローチャート自体もあまりよくないかも)
これは良いでしょうか?
 上の理解されているならパターン2の処理を書く所が
 おかしいということはわかるはず

提示されているソースでは
特定の座標データがパターン1に該当するとして
除去しないデータをif文でチェックしているようです
此処まではいいのですが
その条件に含まれない全てのデータが対象になるということなので

>else if ((bmp.GetPixel(i + 1, j).R != 255) || (bmp.GetPixel(i, j - 1).R != 255))

ではなくて
else
だけになるはずです(というのが条件は要らないのでは? と書いた理由です)

でもってそのelse文になった時に
パターン2の除外条件をチェックするということです

フロー的にその辺あたるが判りにくいような気がしますが
変換後この条件に引っかかる物は質問者さんも書かれているように
当然のごとく存在しません
ですので変換前のオリジナルデータがパターン2に該当していたら
という条件でチェックを継続しなければならないはずです
(ここが書いてあるフローだとわかりにくいかも)

実際やってないので間違っているかもしれませんが
該当1座標のデータとその周辺のデータがパターン1/2に該当している場合
其々の除外しない条件に当てはまるデータ以外のところを
0にしなくてはいけないはずです
    • good
    • 0

内容ちゃんと見てるわけではないですがフローチャートと食い違っているのでは?


(以下部分以降)

>//除去するパターン
>else if ((bmp.GetPixel(i + 1, j).R != 255) || (bmp.GetPixel(i, j - 1).R != 255))

上記のようにパターン1で除去するパターンでif条件が入っていますが
フローでは無条件削除した上で
パターン2に該当するかチェックしている様に見えます

提示ソースでは全体をパターン1だけで処理して
その後パターン2を行おうとしているように思えます

フローチャートでは同一座標に対してパターン1・2の処理を順番に行っています

この回答への補足

「パターン1に該当する場合、画素を除去する」と書いてあるので、無条件で削除するわけではないと思います。(中心が黒になると、パターン2にはひっかからないので)

また、「パターン1に該当する画素が1画素も無ければその時点で終了です」という記述から同一座標に対してパターン1,2を順番に行うのは変じゃないでしょうか?

もう少しアドバイスをお願いします

補足日時:2010/07/26 20:41
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!