任意の形状の自動トリミング


14

バイナリマスクで定義された任意の形状があります(灰色=形状、黒=背景)。

私は灰色のピクセルのみを含む可能な限り大きな長方形を見つけたいです(そのような長方形は黄色で描かれています):

ここに画像の説明を入力してください

形状は常に「ワンピース」ですが、必ずしも凸状ではありません(形状の境界上のすべてのポイントペアが、形状を通る直線で接続できるわけではありません)。

そのような「最大の長方形」の多くが存在する場合があり、その後、次のようなさらなる制約を導入できます。

  • 中心が図形の重心(または画像の中心)に最も近い長方形を撮影する
  • 定義済みの比率(4:3など)に最も近いアスペクト比を持つ長方形を撮影します

ここに画像の説明を入力してください

アルゴリズムについて最初に考えたのは次のとおりです。

  1. 形状の距離変換を計算し、その重心を見つける
  2. シェイプのピクセルのみが含まれる正方形の領域を拡大します
  3. 長方形(元は正方形)の幅または高さを拡大し、形状のピクセルのみが含まれるようにします。

ただし、このようなアルゴリズムは時間がかかり、最適な解決策にはならないでしょう。

助言がありますか?



@AtulIngle完全に!ありがとう。答えを追加してもらえますか?次に、アルゴリズムをさらに詳しく説明するために回答を編集しますが、提供したリンクを使用して自分の質問に回答したくありません...
Libor

すごい!コードを読み終えていないので、詳細な回答を読むのを楽しみにしています。
アトゥルイングル

@AtulIngle OK、答えにいくつかの議論と私の完全な記事へのリンクを追加しました。
リボール

回答:


10

問題に関連するMatlab Fileexchangeのコードがあります:http : //www.mathworks.com/matlabcentral/fileexchange/28155-inscribedrectangle/content/html/Inscribed_Rectangle_demo.html

更新

Atul Ingleからの上記のリンクに基づいて、最大の内接長方形の計算に関するこのチュートリアル記事を書きました。

アルゴリズムは、最初にバイナリマスクで最大の正方形を検索します。これは、単純な動的プログラミングアルゴリズムを使用して行われます。新しいピクセルはそれぞれ、既知の3つの隣接ピクセルを使用して更新されます。

squares[x,y] = min(squares[x+1,y], squares[x,y+1], squares[x+1,y+1]) + 1

ここに画像の説明を入力してください

サンプルのバイナリマスクと計算されたマップは次のようになります。

ここに画像の説明を入力してください ここに画像の説明を入力してください

マップを最大にすると、最大の内接正方形が明らかになります。

ここに画像の説明を入力してください

長方形検索アルゴリズムは、マスクをさらに2回スキャンして、2つの長方形のクラスを探します。

  • 正方形のサイズよりも大きい幅(および場合によっては高さ)
  • 高さが正方形のサイズよりも大きい(および幅が小さい可能性がある)

両方のクラスは最大の正方形で区切られます。これは、与えられたポイントに両方の寸法を内接正方形より大きくすることはできないためです(一方の寸法は大きくできます)。

面積、円周、または寸法の加重合計など、長方形のサイズには何らかのメトリックを選択する必要があります。

長方形の結果のマップは次のとおりです。

ここに画像の説明を入力してください ここに画像の説明を入力してください

マップを構築して最大値を探す代わりに、これまでに見つかった最良の長方形の位置とサイズを変数に保存すると便利です。

ここに画像の説明を入力してください

このアルゴリズムの実用的な用途は、非矩形画像のトリミングです。私は自分の画像ステッチングライブラリSharpStitchでこのアルゴリズムを使用しました

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.