テクスチャの輪郭を抽出できるライブラリを作成しました
「いらすとや」さんの素材をお借りして、ライブラリを使うと
このように上記画像の輪郭を抜き出したり、輪郭を合成することができます
以下のアルゴリズムと使い方を記述します
アルゴリズム
下のテクスチャをもとにアルゴリズムを記述します
左上から探索して対象のピクセルにヒットするまで探索する
開始地点に行くまで、対象ピクセルから周りのピクセルを反時計周りに探索を繰り返す
この際に探索する位置は初回は左下から反時計回り
それ以降はヒットした位置 + 6 が探索開始位置になる
- 1 でヒットすれば次は 7 から
- 3 でヒットすれば次は 1 から
これを繰り返すことで最終的には以下の輪郭が抽出できる
複数輪郭のアルゴリズム
上記のアルゴリズムは、輪郭が一つの場合はこれでいいが輪郭が複数あった場合はこれだけでは動作しません
そのため、以下の画像を参考に複数輪郭の抽出についても記述します
今まで通り輪郭の抽出を行う
輪郭の抽出を行うと左が先に検知できるためこのようになります
先程の検出した輪郭はスキップして次の対象ピクセルを探す
再度探索を開始する際に見つけたところはスキップ、つまり次の開始は (2, 1) ですが (2, 1) はすでに探索済みなので、(3, 1) から探索を開始する
(4, 1) で未探索にヒットするためそこから、輪郭を抽出する
輪郭を抽出後再度探索を開始すると以下のように (4, 4) でまたヒットするので輪郭を抽出する
これを最後のピクセルまで繰り返すことで複数の輪郭を抽出できる
使い方
private void TraceConTour(Texture2D src, Color color, float threshold) { // テクスチャをインスタンスに渡す var contour = new Contour(src); // 輪郭を探す色を指定して輪郭を探す if (!contour.Search(color)) { return; } // 輪郭が見つかった場合輪郭テクスチャを取得できる var texture = contour.GetContourTexture(Color.black); // 輪郭のピクセル座標を取得することもできる contour.Points } // 2値化して輪郭探索 private void SaveBinarizationTexture(Texture2D src, float threshold) { // テクスチャをインスタンスに渡す var contour = new Contour(src); // 必要に応じて2値化する contour.ToBinarization(threshold); // 元々のテクスチャに輪郭を追加して出力 var blendTexture = contour.BlendContourTexture(src, Color.black) : // 2値化したテクスチャを取得 var binarizationTexture = contour.GetBinarizationTexture(); }