バイナリ イメージ内のオブジェクトを認識する必要があります。
私は可能なアルゴリズムを探してインターネットで検索しましたが、それらはたくさんありますが、残念ながら、視覚的な説明なしに生の式をコードアルゴリズムに変換することは個人的に非常に困難です.
このアルゴリズムを見つけましたhttp://www.izbi.uni-leipzig.de/izbi/publikationen/publi_2004/IMS2004_JankowskiKuska.pdf。
さらにJava
、この記事で説明されている実装があります。
著者が書いたように
メソッド labelImage が Mathematica の組み込み関数またはユーザー定義関数として使用できるようになりました
残念ながらそうではありませんが、このアルゴリズムは1
、コーナー、最初、最後の位置の場合、if チェックがないため失敗します。
セルが見つかった場合、アルゴリズムは非常に簡単で、1
まだラベルが付けられていない場合、見つかったアイテムをスタックにプッシュする隣人をチェックします。
しかし、それが正しく機能するかどうかはわかりません。if
私はそれを変更し、範囲外にならないようにいくつかのチェックを追加しました。
ここにあります。
public int[][] labelImage(int stackSize) {
int nRow = img.length;
int nCol = img[0].length;
int marker = 1;
int[] pos;
mStack = new SizedStack<>(stackSize);
int[][] label = new int[nRow][nCol];
for (int r = 0; r < nRow ; r++)
for (int c = 0; c < nCol; c++) {
if (img[r][c] == 0) continue;
if (label[r][c] > 0) continue;
/* encountered unlabeled foreground pixel at position r, c */
/* push the position on the stack and assign label */
mStack.push(new int[]{r, c});
label[r][c] = marker;
/* start the float fill */
while (!mStack.isEmpty()) {
pos = mStack.pop();
int i = pos[0];
int j = pos[1];
// Check if this is not first row, in this case we don't need to check top cells
if (i > 0) {
if (img[i - 1][j - 1] == 1 && label[i - 1][j - 1] == 0) {
mStack.push(new int[]{i - 1, j - 1});
label[i - 1][j - 1] = marker;
}
if (img[i - 1][j] == 1 && label[i - 1][j] == 0) {
mStack.push(new int[]{i - 1, j});
label[i - 1][j] = marker;
}
// Check if this is not the last column cell
if (j != nCol - 1) {
if (img[i - 1][j + 1] == 1 && label[i - 1][j + 1] == 0) {
mStack.push(new int[]{i - 1, j + 1});
label[i - 1][j + 1] = marker;
}
}
}
// Check if this is not first column
if (j > 0) {
if (img[i][j - 1] == 1 && label[i][j - 1] == 0) {
mStack.push(new int[]{i, j + 1});
label[i][j + 1] = marker;
}
// Check if this is not last row
if (i != nRow - 1) {
if (img[i + 1][j - 1] == 1 && label[i + 1][j - 1] == 0) {
mStack.push(new int[]{i + 1, j - 1});
label[i + 1][j - 1] = marker;
}
}
}
// Check if this is not last row
if (i != nRow - 1) {
if (img[i + 1][j] == 1 && label[i + 1][j] == 0) {
mStack.push(new int[]{i + 1, j});
label[i + 1][j] = marker;
}
// Check if this is not first column
if (j != nCol - 1) {
if (img[i + 1][j + 1] == 1 && label[i + 1][j + 1] == 0) {
mStack.push(new int[]{i + 1, j + 1});
label[i + 1][j + 1] = marker;
}
}
}
}
marker++;
}
return label;
}
}
これが例と結果です。
次の画像を検討してください
{1, 0, 0, 0, 0, 1, 0, 1},
{0, 0, 1, 1, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 1, 0, 0},
{0, 1, 0, 1, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
そして結果
[1, 0, 0, 0, 0, 2, 0, 3]
[0, 0, 4, 4, 0, 2, 0, 0]
[0, 0, 0, 4, 0, 2, 0, 0]
[0, 5, 0, 4, 0, 0, 0, 6]
[0, 0, 0, 0, 0, 7, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 8]
[0, 0, 0, 0, 0, 9, 8, 8]
[0, 0, 0, 0, 0, 0, 0, 0]
ここで問題となるのは、6 行目と 7 行目 (1 から開始) です。
私が理解できる限り、このアルゴリズムは 8-cohesion を使用していますが、少し別の方法で考えました。
9 を新しいオブジェクトとして正しく認識していますか? アルゴリズムは、そのような方法で近隣をチェックします (U - チェックされていない、C チェックされている、X - 現在のセル)
CCU
CXU
CCUセル [7,8] のどこが間違っているのですか?なぜマークされているのですか?
全体として、私は画像処理と認識の経験があまりないので、より良いアルゴリズムとその使用例の助けやアドバイスをいただければ幸いです。
ありがとう。