2

私のプロジェクトでは、画像の ROI をトリミングしたいと考えています。このために、関心のある領域を含むマップを作成します。ここで、最も重要なピクセルを含む領域をトリミングしたいと考えています (黒は重要ではなく、白は重要です)。

誰かがそれを実現する方法を知っていますか? これは最大化の問題だと思います下の画像の赤い枠線は、この画像をトリミングする方法の例です 画像

4

1 に答える 1

5

私があなたの質問を正しく理解していれば、画像内のすべてのポイントで値を計算したことになります。これらの値は、各ポイントの「重要性」/「面白さ」/「注目度」を示唆しています。これらの値を含むマトリックス/画像は、参照している「マップ」です。目標は、「重要度」スコアが高い関心領域 (ROI) の境界ボックスを取得することです。

ROI のセグメント化について考えられる方法は、重要度マップを使用して各ピクセルで「スコア」を計算する Graph Cut ベースのセグメンテーションを適用することです。セグメンテーションの結果は、「重要な」ピクセルをマスクするバイナリ マスクです。次に、このバイナリ マスクに対してOpenCV のfindcontours関数を実行して、個々の連結成分を取得します。次に、findContours(...) によって返された輪郭でOpenCV のboundingRect関数を使用して、境界ボックスを取得します。

この方法でグラフ カット ベースのセグメンテーション アルゴリズムを使用することの良い点は、断片化されたコンポーネントを結合することです。つまり、結果として得られるバイナリ マスクには、「重要な」マップにノイズが多い場合でも、小さな穴のポケットがない傾向があります。

OpenCV に既に実装されている Graph Cut ベースのセグメンテーション アルゴリズムの 1 つは、GrabCut アルゴリズムです。簡単なハックは、それを「重要度」マップに適用して、前述のバイナリ マスクを取得することです。より洗練されたアプローチは、「重要度」マップを使用して前景と背景 (おそらく色?) モデルを構築し、それを関数への入力として渡すことです。OpenCV での GrabCut の詳細については、http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=grabcut#voidgrabCut(InputArray img, InputOutputArray mask, Rect rect, InputOutputArray bgdModel, InputOutputArray fgdModel、int iterCount、int モード)

より高い柔軟性が必要な場合は、次の MRF ライブラリを使用して独自のグラフカット ベースのセグメンテーション アルゴリズムをハックできます。このライブラリを使用すると、グラフ カットを計算する際にカスタムの目的関数を指定できます: http://vision.middlebury.edu/MRF/code/

MRF ライブラリを使用するには、画像の各ポイントで「コスト」を指定して、そのポイントが「前景」か「背景」かを示す必要があります。この二分法は、「前景」と「背景」ではなく、「重要」または「重要ではない」と考えることができます。MRF ライブラリの目標は、ラベルを割り当てる総コストができるだけ小さくなるように、各ポイントでラベルを返すことです。したがって、ゲームは、重要であると考えるポイントとそうでない場合は大きいと考えるポイントの小さなコストを計算する関数を考え出すことです。

具体的には、各ポイントでのコストは、1) データ項/関数と 2) 平滑項/関数の 2 つの部分で構成されます。前述のように、各ポイントのデータ項が小さいほど、そのポイントが選択される可能性が高くなります。「重要度」スコア s_ij が [0, 1] の範囲にある場合、データ項を計算する一般的な方法は -log(s_ij) です。

滑らかさの項は、隣接する 2 つのピクセル p、q が同じラベル、つまり「前景」、「背景」の両方、または一方の「前景」ともう一方の「背景」を持つべきかどうかを示唆する方法です。データ コストと同様に、同じラベルが割り当てられるように、類似の「重要度」スコアを持つ隣接ピクセルのコストが小さくなるように構築する必要があります。この用語は、結果のマスクを「平滑化」して、「重要度」の高い領域内に「重要度」の低いピクセルがまき散らされたり、その逆が発生したりしないようにします。そのような領域がある場合、上記の OpenCV の findContours(...) 関数は、これらの領域の輪郭を返します。これは、おそらくサイズをチェックすることで除外できます。

コストを計算する関数の詳細については、GrabCut の論文 ( GrabCut)を参照してください。

このブログ投稿では、OpenCV で独自のグラフカット セグメンテーション アルゴリズムを作成する方法について、もう少し詳しく (およびコードを) 説明しています。 image-segmentation-with-opencv-w-code/

GrabCut ペーパーで、グレースケール画像 (あなたのケース) でグラフ カット セグメンテーションを実行する方法を示す別のペーパーは、より良い表記法を使用し、複雑なイメージ マッティング部分 (OpenCV のバージョンでは実装されていません) を使用しません: Graph Cuts and Efficient ND Image Segmentation

お役に立てれば。

于 2012-12-06T07:58:03.313 に答える