8

グラフィカルな画面で何かを見つけることをいじってみて、私は現在、画像内の特定の形状を見つける方法について途方に暮れています。画像の形状は異なるスケールを持つ可能性があり、もちろん、未知のx、yオフセットになります。

異なるスケールに起因するピクセルアーティファクトは別として、両方の画像にわずかなノイズもあるため、ある程度許容できる検索が必要です。

これが私が探している画像です。

ファーメラマフレーム

それは私の(デュアル)スクリーンバッファのスクリーンダンプのどこかに表示されるはずです。サイズはおよそ3300x1200ピクセルです。もちろんブラウザウィンドウで見つけることを期待していますが、その情報は必要ないはずです。

この演習の目的は(これまでのところ)、次のような結果を出すことです。

  • はい、(そのおおよその色で、おそらくわずかに切り詰められた形の)木製のフレームが私の画面で見つかりました(または見つかりませんでした)。と
  • ゲームのクライアント領域(フレーム内の黒い領域)は、から(x1,y1)までの長方形を占め(x2,y2)ます。

スケーリングやディザリングによって発生する可能性のあるノイズに対して堅牢になりたいです。一方、回転や非剛性など、通常のCVの課題のいくつかを除外することはできます。そのフレームの形状は、人間の脳にとって非常に簡単に識別できますが、専用のソフトウェアではどれほど難しいのでしょうか。これはAdobeFlashアプリケーションであり、最近まで、ゲームGUIからの画像の認識はパイのように簡単なはずだと思っていました。

針と干し草の山の間で可能な限り最大のオーバーラップが発生するx、y変換を見つけることができるアルゴリズムを探しています。可能であれば、一連の可能なスケール係数を繰り返す必要はありません。理想的には、アルゴリズムは、縮尺に依存しない方法で画像の「形状」を抽象化できます。

フーリエ変換についていくつか興味深いことを読んで、似たようなことを達成しました。同じスケールのターゲット画像が与えられた場合、FFTといくつかの行列計算により、検索パターンに対応する大き​​な画像のポイントが得られました。しかし、これを実践するための理論的背景がありません。また、このアプローチがスケールの問題を適切に処理できるかどうかもわかりません。助けていただければ幸いです!

テクノロジー:私はClojure / Javaでプログラミングしていますが、他の言語のアルゴリズムを適応させることができます。私はCの呼び出し規約に従うライブラリとインターフェースできるはずだと思いますが、純粋なJavaソリューションを好みます。


私が実際の画像を提示することを避けた理由を理解できるかもしれません。これはばかげたゲームですが、画面を読み上げる作業は、私が思っていたよりもはるかに難しいことがわかりました。

私は明らかに、画像を構成するピクセル(黒を除く)を画面バッファーで徹底的に検索することができ、1分以内で実行されます。しかし、私の野心は、スケーリングとディザリングから生じる可能性のある違いに関係なく、形状に一致する技術を使用してその木製フレームを見つけることでした。

実際、ディザリングは、このプロジェクトで私が抱えている多くのフラストレーションの1つです。私はエッジ抽出によっていくつかの有用なベクトルを抽出することに取り組んできましたが、特定の領域のピクセルは広く一貫性のない色を持っているため、エッジはひどくとらえどころのないものです-したがって、ローカルのディザリングアーティファクトから実際のエッジを区別するのは難しいです。このようなシンプルなゲームが、ソフトウェアが認識しにくいグラフィックを生成することになるとは思いもしませんでした。

機能を探し始める前に、ピクセルをローカルで平均化することから始める必要がありますか?ピクセルカラー値の最下位ビットを破棄して、色深度を減らす必要がありますか?

私は純粋なJavaソリューション(実際にはClojure / Javaミックスでプログラミング)を試しているので、opencv(.DLLまたは.soをCコードでインストールする)に夢中ではありません。私の言語の選択について心配する必要はありません。学習体験はパフォーマンスよりもはるかに興味深いものです。

4

3 に答える 3

11

コンピュータービジョンの人である私は、通常、特徴抽出とマッチング(SIFT、SURF、LBPなど)を指しますが、これらの方法のほとんどはより多くの不変性(=変換に対する許容度)を提供するため、これはほぼ間違いなくやり過ぎです。実際に必要な量よりも多くなります(たとえば、回転、輝度の変化などに対して)。また、機能の使用には、OpenCVまたは多くのプログラミングが含まれます。

だからここに簡単な解決策の私の提案があります-あなたはそれが賢さのしきい値を超えるかどうかを判断します:

あなたが探している画像はいくつかの非常に明確な構造(文字、ロゴなど)を持っているように見えます。可能なすべての翻訳、およびいくつかの異なるスケール(スケールの範囲は限られていると思います)に対してピクセル間一致を行うことをお勧めしますが、探している画像の小さな特徴的なパッチに対してのみです(たとえば、黄色のテキストの正方形の部分)。これは、全体を一致させるよりもはるかに高速です。派手な名前が必要な場合:画像処理では、相関によるテンプレートマッチングと呼ばれます。「テンプレート」はあなたが探しているものです。

小さな特徴的なパッチの候補となる場所をいくつか見つけたら、画像全体、またはより効率的には画像の他のいくつかの特徴的なパッチをテストすることで、ヒットしたことを確認できます(もちろん、翻訳/あなたが見つけたスケール)。これにより、パフォーマンスをあまり損なうことなく、元のパッチの偶発的な一致に対して検索が堅牢になります。

ディザリングの許容範囲については、両方の画像(探しているテンプレートと検索スペースである画像)の単純な事前フィルタリングを行います。ディザリングのプロパティに応じて、単純なボックスブラーの実験を開始し、それが機能しない場合は、おそらく小さなカーネル(3 x 3)のメディアンフィルターに進むことができます。これにより、テンプレートと検索された画像の間で100%の同一性が得られるわけではありませんが、比較できる堅牢な数値スコアが得られます。

コメントに照らして編集する

(1)ソリューションとして、より堅牢で「CVに似た」、もう少し凝ったものが必要であり、(2)さまざまなスケールの大きなスタックをスキャンするだけで、スケール不変性を実現することに懐疑的であることを理解しています。

(1)に関して、標準的なアプローチは、前述のように、機能記述子を使用することです。特徴記述子は、完全な画像(または形状)を記述しませんが、さまざまな変換に対して不変の方法で画像のごく一部を記述します。SIFTSURF、およびVLFeatを見てください。VLFeatは、優れたSIFT実装を持ち、 MSERHOGも実装しています(OpenCVよりもはるかに小さいです)。SURFはSIFTよりも実装が簡単で、どちらも特許を取得しています。どちらにも「直立」バージョンがあり、回転不変性はありません。これにより、ケースの堅牢性が向上するはずです。

コメントで説明する戦略は、画像の特徴記述子よりも形状記述子の方向に向かっています。それらの違いを理解してください!2D形状記述子は、通常、アウトラインまたはバイナリマスクによって記述される形状を対象としています。画像特徴記述子(上記の意味での使用)は、強度値を持つ画像(通常は写真)を対象としています。興味深い形状記述子は形状コンテキストです。他の多くの記述子がここに要約されています。あなたの問題が形状記述子によって最もよく解決されるとは思いませんが、おそらく私は何かを誤解しました。一次導関数であるエッジはディザリングノイズによって大幅に変更される可能性があるため、画像エッジの形状記述子には非常に注意します。

(2)について:コンピュータビジョンを知らない人にとって、さまざまなスケールをスキャンすることは、単なる愚かなハックではないことを納得させたいと思います。実際、それはビジョンの中で多くのことを成し遂げました、私たちはそれが未経験のスケールスペース検索を誤解させるためにそれの空想的な名前を持っています。これは少し単純化しすぎていますが、実際には少しだけです。実際に使用されるほとんどの画像特徴記述子は、スケール空間を使用してスケール不変性を実現します。スケール空間は、ますますダウンスケールされた(およびローパスフィルター処理された)画像のスタックです。彼らが追加する唯一のトリックは、スケール空間で極値を探し、それらの極値でのみ記述子を計算することです。しかし、それでも、完全なスケールスペースが計算され、それらの極値を見つけるためにトラバースされます。元のSIFTペーパーをご覧くださいこれの良い説明のために。

于 2013-02-26T14:34:42.847 に答える
2

良い。私はかつて、画面をキャプチャすることによってフラッシュゲームにいくつかのチートを実装しました:)。画像で指定した正確な境界線を見つける必要がある場合は、カラーフィルタを作成して残りをすべて削除すると、さらに処理するために使用できるバイナリ画像が得られます(手元のタスクは見つけることです)特定の境界比を持つ一致する長方形。また、いくつかの異なるスケールでコーナーを見つける4つのカーネルを実装できます。

画像ストリームがあり、動きがあることがわかっている場合は、背景モデリングソリューションを使用して、フレーム間の違いを監視し、画面内のアクションパーツをキャプチャすることもできます。これらを組み合わせると、マルチスケール分析などのよりエキゾチックな方法に頼ることなく、かなり遠くまで到達できると思います。

パフォーマンスに問題がありますか?私のチートは、ボールを十分速くクリックする必要があるため、約20fpsを使用しました。

于 2013-02-25T20:23:22.210 に答える
0

私は自分の質問に対する答えを報告して、私がこれをどこに行ったのかを人々に知らせています。


探していた魔法のスケール不変の形状記述子についてのヒントが見つからなかった、または得られなかったので、DCSのアドバイスに従って、画面全体でほぼまっすぐなピクセル検索を実行することにしました。

まず、ロゴの512x60チャンクを検索しました。しかし、最終的にクワッドネストループ(完全な画像の行/列x検索画像の行/列)になるのは、最悪の場合、1時間以上実行されることがわかりました。受け入れられない。

約48x32ピクセルのパッチである、より小さな検索画像を選択することで、問題を直線的に縮小することができました。これは私が約30秒かかったと思いますが、それでも私が思っていたよりも遅かったです。また、後で他の機能を検索しようとすると、時間がかかるでしょう。

私の解決策は、検索画像の1つのスキャンラインのみを検索し、それを完全にではなくプロキシで検索することでした。私が探していた画像のコミックカラーの性質のために、私は平均的な色相が私が探していたピクセルのまともなプロキシを作るだろうと決めました。検索画像の「中央」の行を選択し、各ピクセルの色相を(0〜7200の整数として)抽出し、それらの色相値の合計を計算しました。画面画像では、検索画像の幅に対応するピクセル数の移動合計を計算したため、各ピクセル位置について、最も古いピクセルを差し引き、新しいピクセルを1つ追加するだけで済みます。Javaを使用するColor.rgbToHSBと、特にへの変換に照らして、最適化の可能性が残ります。floatと戻って、しかし、画面全体が数百ミリ秒で事前にサンプリングされる可能性があります。

そこで、画面の色相の合計と検索画像の中央線の違いのリストを作成し、最良の(つまり最小の)違いを見つけてから、1位を共有する位置についてピクセルごとに完全な比較を行いました。通常、これらの最適な色の合計一致は10未満であったため、10ピクセルごとの比較にかかる時間はごくわずかでした。

だから今、私は約0.5秒で検索画像を見つけていますが、いくつかの最適化の可能性はまだ活用されていません。より多くの異なるスケールを「実行」する必要がある場合は、解像度が異なると、試行錯誤せずに別の検索画像を選択できるようになりますが、最悪の場合、比較作業のごく一部のみを複数回実行する必要があります。まだ1秒未満にとどまると予想します。

探している画像のさまざまなディザー(つまり、詳細なピクセルレンディション)に対して非常に耐性があるという当初の目標を達成していません。私のアルゴリズムでは、色をうまく一致させる必要があります。しかし、それがどれほど難しい問題であるかを考えると、私は必要があればその橋を渡ることに決めました。

于 2013-03-05T16:49:18.767 に答える