ヒント:
他の回答で述べたように、アウトライン ピクセルのリストを出力することは、実行エンドポイントの 3x3 近傍が検査されるスイープライン プロセスとして実装できます。
この手順では、保存して並べ替える必要がある一連の直接アークと逆アークとして、スクランブルされた方法でピクセルを放出します。
別の方法として、希望する順序でアウトライン ピクセルを列挙する利点を持つ標準の Moore Neighborhood アルゴリズムを実装するというアイデアに基づくものがあります。
この手順では、現在のピクセルの周囲の 8 つの近傍構成を知る必要があります。この考え方は、別のピクセルに移動するたびにこの近傍を更新することです。現在のピクセルを含むランと、行内の 2 つの向かい合ったランへのインデックスを維持します。上と下。
別のピクセルに移動するたびに、これら 3 つのインデックスを更新する必要があります。これには、並べ替えられたランのリストでの短い順次検索が含まれます。これは、ピクセルへの疑似ランダム アクセス メカニズムと見なすことができます。これは、連続するアクセスが非常にローカルであり、一種のキャッシュが可能であることを考慮に入れることができます。
更新:
私が使用するランレングス コード表現では、黒いランのみがトリプルとしてコード化され(X, Y, L)
ます。実行は行ごとに上から下に並べ替えられ、次に左から右に並べられます。
便宜上、すべての画像行が次々に追加され、すべてのピクセルが 1 つの数値Z = X + Y.Nx
(Nx
は画像の幅) で指定されているかのように、"リニア アドレス指定" スキームに切り替えることができます。
したがって、黒のランのリストがあり、白のランは 2 つの連続する黒のランの間に暗黙的に検出されます。
処理中、現在のピクセルの直前またはそのピクセルで始まるランのインデックスを常に覚えておくことができます ( R[I].Z <= Z < R[I+1].Z
)。ランの内側にいるか、ランと次の間にあるかを確認することで、ピクセルの色を知ることができます ( Z < R[I].Z + R[I].L
)。
位置を 1 つ左に移動すると、Z
が減少し1
、前の実行を選択する必要がある場合があります ( I--
)。
1 ポジション上に移動すると、Z
減少しNx
、数回の実行でバックトラックする必要がある場合があります (再び実行さI--
れるまでR[I].Z <= Z
)。
この図は、現在のピクセルとその 4 つの隣接ピクセル、および黒ランの「影響ゾーン」を示しています。8 つの変位方向すべてを同様に処理できます。
ご覧のとおり、すべての移動は、小さな値と見なされる、連続した実行の数に等しい悪い操作を必要とします。この概念を使用すると、ビットマップ全体を再構築することなく、妥当なコストで任意のパスに従って RLC 表現をトラバースできます。
Moore Neighborhood アルゴリズムは、アウトラインの長さに線形に時間がかかるため、この線形実行アドレス指定に基づく実装も線形時間になります (行ごとの実行数が制限されている場合)。