- 締切済み
細線化のプログラム
細線化のプログラム C#で細線化のプログラムを作成してみましたがうまくいきません。 http://imagingsolution.blog107.fc2.com/blog-entry-138.html を参考に作成しました。 うまくいかないところは、一部に縦線がいくつも残ってしますところです。 ソース 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も同じようにする*/ という感じでプログラムを組んでいます。 画像は失敗例です。アドバイスをお願いします
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- koi1234
- ベストアンサー率53% (1866/3459)
- Akira_Imaging
- ベストアンサー率60% (3/5)
補足です。 同一座標と言っていた部分が気になったので。 処理的にはこんな感じです。 while { for () { for () { //パターン1の除去 } } if (パターン1で除去しなかったら終了) for () { for () { //パターン2の除去 } } if (パターン2で除去しなかったら終了) } という具合です。 なので、1画面分ごとにパターン1の除去、パターン2の除去を繰り返します。 それでも、縦の線は残るような気もしますが、除去する/しないのパターンが間違えていないか?確認してみて下さい。
- Akira_Imaging
- ベストアンサー率60% (3/5)
koi1234さんがパターン1、パターン2を交互に繰り返すと言っていますが、それが正解です。 細線化では、ほぼ線の中心付近を1画素の線として残すように処理をしていきますが、パターン1では、線の右、上の方向から線を細くし、パターン2では線の左、下の方向から線を細くする処理を行っています。 そこで、今回の失敗例のプログラムを見ると、パターン1を繰り返してから、パターン2の繰り返しを行っているので、失敗例の線の位置は、もともとの線の位置の左下に偏っていませんか?
- kmee
- ベストアンサー率55% (1857/3366)
これ、同時に置き換えないとだめだと思うんですが。 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)); } } } と、する、といったことが必要ではないんでしょうか
- koi1234
- ベストアンサー率53% (1866/3459)
文書の為意味が上手く伝わっていないようです まずフローチャートに関してですが画面全体に対しての フローチャートを描いているのではなく 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にしなくてはいけないはずです
- koi1234
- ベストアンサー率53% (1866/3459)
内容ちゃんと見てるわけではないですがフローチャートと食い違っているのでは? (以下部分以降) >//除去するパターン >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を順番に行うのは変じゃないでしょうか? もう少しアドバイスをお願いします