バイナリ イメージ (1 とゼロの 2D マトリックス) を塗りつぶすための matlab 関数 "imfill" をシミュレートしようとしています。
マトリックスの開始点を指定したいのですが、imfill の 4 つの接続バージョンのように塗りつぶします。
これは C++ の世界のどこかに既に存在しますか? そうでない場合、これを実装する最も効率的な方法は何ですか?
バイナリ イメージ (1 とゼロの 2D マトリックス) を塗りつぶすための matlab 関数 "imfill" をシミュレートしようとしています。
マトリックスの開始点を指定したいのですが、imfill の 4 つの接続バージョンのように塗りつぶします。
これは C++ の世界のどこかに既に存在しますか? そうでない場合、これを実装する最も効率的な方法は何ですか?
画像が1と0の2D配列である場合、実際のグラフィックライブラリは必要ないと思います。
過去に単純なグリッドを入力したときは、STLキューを使用してポイントのリストを格納し、それらを処理しました。キューは最初のポイントから始まり、次に隣接するポイントをテストします。隣接するポイントを「フラッド」に含める必要がある場合は、それらをキューに追加します。このようなもの:
// using this data structure
struct Point {
int x;
int y;
};
//
void fillGrid(Point orig, byte** grid, int width, int height) {
std::queue<Point> q;
q.push(orig);
// the main flood loop
while(!q.empty()) {
Point pnt = q.front();
q.pop();
// grab adjacent points
Point adj[4];
adj[0].x = pnt.x; adj[0].y = pnt.y-1; // up
adj[1].x = pnt.x+1; adj[1].y = pnt.y; // right
adj[2].x = pnt.x; adj[2].y = pnt.y+1; // down
adj[3].x = pnt.x-1; adj[3].y = pnt.y; // left
for(int i = 0; i < 4; i++) {
// don't forget boundaries!
if(adj[i].x < 0 || adj[i].x >= width ||
adj[i].y < 0 || adj[i].y >= height)
continue;
// if adjacent point meets some criteria, then set
// its value and include it in the queue
if(includePoint(adj[i], grid)) {
setPoint(adj[i], grid);
q.push(adj[i]);
}
}
}
}
C ++で画像処理を行う場合は、 OpenCV(Open Source Computer Vision)を調べる必要があります。
それは画像/ビデオ処理のための素晴らしいクロスプラットフォームライブラリであり、あなたが探しているものを持っています。この質問を確認してください:
このページのコード例を参照してください (「QuickFill: 効率的なフラッド フィル アルゴリズム」)
最初のいくつかのコード例では、ピクセルが塗りつぶし (または境界線) の色を持っているかどうかがチェックされ、関数は 4 つ (または 8 つ) の隣接ピクセルすべてに対して再帰的にそれ自体を呼び出します (実際、最初のいくつかの例は少し間違っていると主張します。最初の再帰呼び出しは、まったく同じパラメーターで関数自体を再度呼び出すのではなく、新しいピクセルを設定する関数の呼び出しにする必要があります)。
次のいくつかの例では、再帰的なスキャン ライン メソッドについて説明します。これは、隣接するライン (上下のライン) に移動する前に、最初に (水平) ラインを可能な限り埋めて、各ピクセルにアクセスする頻度を減らします。
QuickFill
最後に、私にはどれが走査線法の最適化された変種のように見えるかを提案します。
Aforge ライブラリには次の機能があります。
AForge.Imaging.Filters.FillHoles(...)
Matlab の imfill と同じことを行います。