1803

One of the most interesting projects I've worked on in the past couple of years was a project about image processing. The goal was to develop a system to be able to recognize Coca-Cola 'cans' (note that I'm stressing the word 'cans', you'll see why in a minute). You can see a sample below, with the can recognized in the green rectangle with scale and rotation.

Template matching

Some constraints on the project:

  • The background could be very noisy.
  • The can could have any scale or rotation or even orientation (within reasonable limits).
  • The image could have some degree of fuzziness (contours might not be entirely straight).
  • There could be Coca-Cola bottles in the image, and the algorithm should only detect the can!
  • The brightness of the image could vary a lot (so you can't rely "too much" on color detection).
  • The can could be partly hidden on the sides or the middle and possibly partly hidden behind a bottle.
  • There could be no can at all in the image, in which case you had to find nothing and write a message saying so.

So you could end up with tricky things like this (which in this case had my algorithm totally fail):

Total fail

I did this project a while ago, and had a lot of fun doing it, and I had a decent implementation. Here are some details about my implementation:

Language: Done in C++ using OpenCV library.

Pre-processing: For the image pre-processing, i.e. transforming the image into a more raw form to give to the algorithm, I used 2 methods:

  1. Changing color domain from RGB to HSV and filtering based on "red" hue, saturation above a certain threshold to avoid orange-like colors, and filtering of low value to avoid dark tones. The end result was a binary black and white image, where all white pixels would represent the pixels that match this threshold. Obviously there is still a lot of crap in the image, but this reduces the number of dimensions you have to work with. Binarized image
  2. Noise filtering using median filtering (taking the median pixel value of all neighbors and replace the pixel by this value) to reduce noise.
  3. Using Canny Edge Detection Filter to get the contours of all items after 2 precedent steps. Contour detection

Algorithm: The algorithm itself I chose for this task was taken from this awesome book on feature extraction and called Generalized Hough Transform (pretty different from the regular Hough Transform). It basically says a few things:

  • You can describe an object in space without knowing its analytical equation (which is the case here).
  • It is resistant to image deformations such as scaling and rotation, as it will basically test your image for every combination of scale factor and rotation factor.
  • It uses a base model (a template) that the algorithm will "learn".
  • Each pixel remaining in the contour image will vote for another pixel which will supposedly be the center (in terms of gravity) of your object, based on what it learned from the model.

In the end, you end up with a heat map of the votes, for example here all the pixels of the contour of the can will vote for its gravitational center, so you'll have a lot of votes in the same pixel corresponding to the center, and will see a peak in the heat map as below:

GHT

Once you have that, a simple threshold-based heuristic can give you the location of the center pixel, from which you can derive the scale and rotation and then plot your little rectangle around it (final scale and rotation factor will obviously be relative to your original template). In theory at least...

Results: Now, while this approach worked in the basic cases, it was severely lacking in some areas:

  • It is extremely slow! I'm not stressing this enough. Almost a full day was needed to process the 30 test images, obviously because I had a very high scaling factor for rotation and translation, since some of the cans were very small.
  • It was completely lost when bottles were in the image, and for some reason almost always found the bottle instead of the can (perhaps because bottles were bigger, thus had more pixels, thus more votes)
  • Fuzzy images were also no good, since the votes ended up in pixel at random locations around the center, thus ending with a very noisy heat map.
  • In-variance in translation and rotation was achieved, but not in orientation, meaning that a can that was not directly facing the camera objective wasn't recognized.

Can you help me improve my specific algorithm, using exclusively OpenCV features, to resolve the four specific issues mentioned?

I hope some people will also learn something out of it as well, after all I think not only people who ask questions should learn. :)

4

23 に答える 23

734

別のアプローチは、スケール不変特徴変換(SIFT)またはSpeeded Up Robust Features(SURF)を使用して特徴(キーポイント)を抽出することです。

、、およびこのページで、優れたOpenCVコード例を見つけることができます。既知のオブジェクトを見つけるためのFeatures2D + HomographyJavaC++Python

どちらのアルゴリズムも、スケーリングと回転に対して不変です。これらは機能で動作するため、オクルージョンを処理することもできます(十分なキーポイントが表示されている限り)。

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

画像ソース:チュートリアルの例

SIFTの処理には数百ミリ秒かかります。SURFは少し高速ですが、リアルタイムアプリケーションには適していません。ORBは、回転不変性に関して弱いFASTを使用します。

元の論文

于 2012-04-16T05:17:39.570 に答える
422

作業をスピードアップするために、任意の画像/オブジェクトを見つけるように求められるのではなく、具体的にはコカ・コーラのロゴが付いたものを見つけるように求められるという事実を利用します. このロゴは非常に特徴的であり、周波数領域、特に RGB の赤チャネルで特徴的なスケール不変の署名を持つ必要があるため、これは重要です。つまり、水平スキャン ライン (水平に配置されたロゴでトレーニング) が遭遇する赤、白、赤の交互パターンは、ロゴの中心軸を通過する際に独特の「リズム」を持ちます。そのリズムは、さまざまなスケールや向きで「加速」または「減速」しますが、比例的には同等のままです。ロゴを通る水平方向と垂直方向の両方、およびさらにいくつかの斜めに、数十のそのようなスキャンラインを識別/定義できます。スターバースト パターンで。これらを「シグネチャ スキャン ライン」と呼びます。

署名走査線

ターゲット画像でこの署名を検索するには、画像を水平方向のストリップでスキャンするだけです。赤チャンネルで高周波数を探し (赤の領域から白の領域への移動を示します)、見つかったら、トレーニング セッションで特定された周波数リズムのいずれかがそれに続くかどうかを確認します。一致が見つかれば、スキャンラインの方向とロゴ内の位置がすぐにわかります (トレーニング中にそれらを追跡している場合)。そのため、そこからロゴの境界を特定するのは簡単です。

これが線形効率の良いアルゴリズムでなかったら、あるいはほとんどそうでなかったら、私は驚くだろう。もちろん、缶ボトルの差別化には対応していませんが、少なくともロゴは表示されます。

(更新:ボトルを認識するために、ロゴに隣接するコーラ(茶色の液体)、つまりボトルの内側を探します。または、空のボトルの場合は常に基本的な形状、サイズ、ロゴからの距離は同じで、通常はすべて白または赤になります. ロゴに対して、キャップがあるべき場所に無地の楕円形を探します. もちろん絶対確実ではありませんが、ここでの目標は簡単なものをすばやく見つけてください。)

(私の画像処理時代から数年が経ちましたので、この提案は高レベルで概念的なものにとどめました。人間の目がどのように機能するか、または少なくとも私の脳がどのように機能するかに少し似ていると思います!)

于 2012-04-17T21:06:00.240 に答える
174

面白い問題: あなたのボトルの画像をちらりと見たとき、これも缶だと思いました。しかし、人間として違いを見分けるために私がしたことは、それがボトルでもあることに気がついたということです...

では、缶とボトルを見分けるには、まずボトルをスキャンしてみませんか? 見つけた場合は、缶を探す前にラベルをマスクしてください。

すでに缶詰を行っている場合、実装するのはそれほど難しくありません。本当の欠点は、処理時間が 2 倍になることです。(しかし、実際のアプリケーションを先に考えると、とにかくボトルをやりたくなるでしょう ;-)

于 2012-04-16T05:03:20.650 に答える
142

2枚目の画像でボトルと缶を見分けるのは人間でも難しいのではないでしょうか?

非常に小さな領域を除いてほとんど同じです (つまり、缶の上部の幅が少し小さいのに対し、ボトルのラッパーは全体で同じ幅ですが、マイナーな変更ですよね?)

最初に頭に浮かんだのは、ボトルの赤い上部を確認することでした. ただし、ボトルの上部がない場合、または部分的に隠れている場合 (上記のように) は、依然として問題です。

次に思ったのは、ボトルの透明度です。OpenCV には、画像内の透明なオブジェクトを見つけるいくつかの作業があります。以下のリンクを確認してください。

特にこれを見て、ガラスをどれだけ正確に検出しているかを確認してください。

実装結果を参照してください。

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

K. McHenry と J. Ponce による CVPR 2006 の論文「A Geodesic Active Contour Framework for Finding Glass」の実装であると彼らは言います。

あなたの場合には少し役立つかもしれませんが、ボトルがいっぱいになると再び問題が発生します.

ここでは、ボトルの透明な本体を最初に検索するか、横方向に 2 つの透明なオブジェクトに接続されている赤い領域を検索できます。これは明らかにボトルです。(理想的に作業しているときは、以下のようなイメージです。)

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

これで、黄色の領域、つまりボトルのラベルを削除し、アルゴリズムを実行して缶を見つけることができます。

とにかく、このソリューションには、他のソリューションと同様にさまざまな問題があります。

  1. ボトルが空の場合にのみ機能します。その場合、2 つの黒色の間の赤色の領域を検索する必要があります (コカコーラの液体が黒色の場合)。
  2. 透明な部分が覆われている場合の別の問題。

とにかく、写真に上記の問題がなければ、これはより良い方法のようです.

于 2012-04-18T23:02:32.137 に答える
54

この問題に対するDarren Cookstacker の回答がとても気に入っています。私はそれらについてのコメントに私の考えを投げかけている最中でしたが、私のアプローチはあまりにも答えの形をしていると思います.

要約すると、コカ・コーラのロゴが空間の特定の場所に存在することを判断するアルゴリズムを特定しました。あなたは今、任意の向きと任意の倍率について、コカ・コーラの缶を他のオブジェクトと区別するのに適したヒューリスティックを決定しようとしています。これには、ボトル看板広告、およびコカ・コーラの道具がすべてこの象徴的なロゴに関連付けられています。問題の説明では、これらの追加のケースの多くは言及されていませんが、アルゴリズムの成功にはそれらが不可欠だと思います。

ここでの秘訣は、缶にどのような視覚的特徴含まれているか、またはネガティブ スペースを通じて、缶にはない他のコーラ製品にどのような特徴があるかを判断することです。そのために、現在の上位の回答は、ボトルのキャップ、液体、または他の同様の視覚的ヒューリスティックの存在によって「ボトル」が識別されない場合にのみ、「缶」を選択するための基本的なアプローチを概説しています。

問題は、これが崩壊することです。たとえば、ボトルが空でキャップがない場合、誤検出につながる可能性があります。または、追加の機能が壊れた部分的なボトルである可能性があり、これが再び誤検出につながる可能性があります。言うまでもなく、これは洗練されたものではなく、私たちの目的には効果的ではありません。

この目的のために、缶の最も正しい選択基準は次のように思われます。

  • 質問でスケッチしたように、オブジェクトのシルエットの形状は正しいですか? もしそうなら、+1。
  • 自然光または人工光の存在を想定した場合、ボトルがアルミニウム製であるかどうかを示すクロムの輪郭をボトルに検出しますか? もしそうなら、+1。
  • オブジェクトの鏡面反射特性が光源に対して正しいと判断できますか (光源検出に関する説明ビデオ リンク)。もしそうなら、+1。
  • ロゴのトポロジー画像の歪み、オブジェクトの向き、オブジェクトの並置 (たとえば、平面上) を含むがこれらに限定されない、オブジェクトを缶として識別するオブジェクトに関するその他のプロパティを決定できますか?テーブルのように、または他の缶のコンテキストで)、およびプルタブの存在? もしそうなら、それぞれに+1。

分類は次のようになります。

  • 一致する候補ごとに、Coca Cola のロゴの存在が検出された場合は、灰色の境界線を引きます。
  • +2 を超える各マッチについて、赤い境界線を引きます。

これにより、何が検出されたかがユーザーに視覚的に強調され、破損した缶として正しく検出される可能性のある弱い陽性が強調されます。

各プロパティの検出は、非常に異なる時間と空間の複雑さを伴います。各アプローチについて、 http://dsp.stackexchange.comをすばやく通過することは、目的に最も正確で最も効率的なアルゴリズムを決定するのに合理的です。ここでの私の意図は、純粋かつ単純に、候補検出スペースのごく一部を無効にすることによって何かが缶であるかどうかを検出することは、この問題に対する最も堅牢または効果的な解決策ではないことを強調することであり、理想的には、適切なアクションを実行する必要があります。によると。

そして、Hacker News への投稿、おめでとうございます! 全体として、これは宣伝に値する非常に素晴らしい質問です。:)

于 2012-04-22T22:56:27.607 に答える
42

形を見る

缶・びんの赤い部分の形に注目してください。ボトルのラベルが真っ直ぐなのに対し、缶の一番上がわずかに先細になっていることに注目してください。この 2 つを区別するには、赤い部分の幅と長さを比較します。

ハイライトを見ると

ビンと缶の見分け方の一つに素材があります。ボトルはプラスチックでできていますが、缶はアルミニウム金属でできています。十分に明るい状況では、スペキュラリティを見ることは、ボトルのラベルと缶のラベルを区別する 1 つの方法です。

私が知る限り、それが人間が 2 種類のラベルの違いを見分ける方法です。照明条件が悪い場合、とにかく 2 つを区別する際に不確実性が生じます。その場合、透明/半透明のボトル自体の存在を検出できる必要があります。

于 2012-04-16T08:31:29.263 に答える
38

ZdenekKalalのプレデタートラッカーをご覧ください。ある程度のトレーニングが必要ですが、追跡対象のオブジェクトがさまざまな方向やスケールでどのように見えるかを積極的に学習し、リアルタイムで実行できます。

ソースコードは彼のサイトで入手できます。これはMATLABにありますが、おそらくコミュニティメンバーによってすでに行われているJava実装があります。TLDのトラッカー部分をC#で正常に再実装しました。私の記憶が正しければ、TLDはキーポイント検出器としてFernsを使用しています。代わりにSURFまたはSIFTのいずれかを使用して(@stackerによってすでに提案されています)、トラッカーによってオブジェクトが失われた場合にオブジェクトを再取得します。トラッカーのフィードバックにより、時間の経過とともにオブジェクトを非常に高い精度で再取得できるシフト/サーフテンプレートの動的リストを時間の経過とともに簡単に作成できます。

トラッカーの私のC#実装に興味がある場合は、お気軽にお問い合わせください。

于 2012-04-17T20:56:15.107 に答える
36

制約の 1 つに含まれていないカメラだけに限定されていない場合は、おそらく Xbox Kinectのような距離センサーの使用に移行できます。これにより、画像の深度と色に基づいた一致したセグメンテーションを実行できます。これにより、画像内のオブジェクトをより高速に分離できます。次に、ICP マッチングまたは同様の手法を使用して、缶の輪郭や色だけでなく形状を一致させることもできます。これは、ターゲットの以前の 3D スキャンがある場合、円筒形であるため、どの向きでも有効なオプションになる可能性があります。これらのテクニックは、速度の問題を解決する特定の目的で使用する場合は特に、非常に高速です。

また、必ずしも精度や速度が求められるわけではありませんが、楽しみのために、色相でセグメント化された画像に対してトレーニング済みのニューラル ネットワークを使用して、缶の形状を特定することをお勧めします。これらは非常に高速で、多くの場合、最大で 80/90% の精度が得られます。ただし、各画像の缶を手動で識別する必要があるため、トレーニングは少し長いプロセスになります。

于 2012-04-16T04:54:25.920 に答える
25

これは非常に単純なアイデアかもしれませんが(またはまったく機能しない場合もあります)、すべてのコークス缶の寸法は固定されています。したがって、同じ画像に缶とボトルの両方が含まれている場合は、サイズを考慮してそれらを区別できます(ボトルは大きくなります)。奥行きがないため(つまり、3Dマッピングから2Dマッピング)、ボトルが縮んで見える可能性があり、サイズの違いはありません。ステレオイメージングを使用して深度情報を復元してから、元のサイズを復元することができます。

于 2012-04-16T05:13:11.850 に答える
25

私は赤い四角形を検出します: RGB -> HSV、フィルター赤 -> バイナリ イメージ、閉じる(膨張してから浸食、imclosematlab で知られている)

次に、長方形を最大から最小まで見ていきます。小さい方の長方形が既知の位置/スケールにある長方形は、両方とも削除できます (ボトルの比率が一定であると仮定すると、小さい方の長方形はボトルのキャップになります)。

これにより、赤い四角形が残るため、何らかの形でロゴを検出して、赤い四角形かコーラの缶かを判断する必要があります。OCR に似ていますが、既知のロゴがありますか?

于 2012-04-16T06:34:38.113 に答える
18

私はOpenCVに気づいていませんが、論理的に問題を見ると、探しているイメージ、つまりコカ・コーラを変更することで、ボトルと缶を区別できると思います。缶の場合はコカコーラの上部に銀の裏地があり、ボトルの場合はそのような銀の裏地がないので、缶の上部まで組み込む必要があります。

しかし、明らかにこのアルゴリズムは、缶の上部が隠されている場合は失敗しますが、そのような場合、人間でさえ2つを区別することはできません(ボトル/缶のコカコーラ部分のみが表示されている場合)

于 2012-04-19T07:15:46.100 に答える
16

私はその挑戦が好きで、問題を解決する答えを出したかったと思います.

  1. ロゴの特徴 (キーポイント、SIFT、SURF などの記述子) を抽出する
  2. ポイントをロゴのモデル画像と一致させます( Brute Force などのMatcherを使用)
  3. 剛体の座標を推定する (PnP 問題 - SolvePnP)
  4. 剛体に合わせてキャップ位置を推定する
  5. 逆投影を行い、ボトルのキャップの画像ピクセル位置 (ROI) を計算します (カメラの固有パラメーターがあると仮定します)。
  6. キャップの有無を方法で確認してください。もしあれば、これはボトルです

キャップの検出は別の問題です。複雑でも単純でもかまいません。私があなたなら、ROI のカラー ヒストグラムをチェックして、簡単な判断を下します。

私が間違っている場合は、フィードバックをお願いします。ありがとう。

于 2013-09-24T14:14:11.817 に答える
13

トピックから外れているかどうかに関係なく、私はあなたの質問が好きです:P

興味深いことはさておき。ロボット工学とコンピューター ビジョンを扱った学位の科目を修了したところです。学期の私たちのプロジェクトは、あなたが説明したものと信じられないほど似ていました.

Xbox Kinect を使用して、さまざまな照明条件や環境条件であらゆる向きのコーラのボトルや缶を検出するロボットを開発する必要がありました。私たちのソリューションは、ハフ サークル変換と組み合わせて色相チャネルでバンドパス フィルターを使用することでした。環境を少し制約することができました (ロボットと Kinect センサーを配置する場所と方法を選択できました)。それ以外の場合は、SIFT または SURF 変換を使用する予定でした。

このトピックに関する私のブログ投稿で私たちのアプローチについて読むことができます:)

于 2013-01-04T06:10:22.317 に答える
11

オブジェクトの認識に使用される色記述子はたくさんあります。以下の論文では、それらの多くを比較しています。SIFT や SURF と組み合わせると特に強力です。SURF または SIFT だけでは、コカ・コーラの缶の画像ではあまり役に立ちません。それらは多くの関心点を認識しないためです。そのためには色情報が必要です。プロジェクトで SURF と一緒に BIC (Border/Interior Pixel Classification) を使用していますが、オブジェクトの認識に非常に役立ちました。

Web 画像検索のための色記述子: 比較研究

于 2013-01-03T15:26:41.543 に答える
2

何年も遅れているかもしれませんが、それでも試してみる理論です。

ボトル/缶の全体の寸法に対する赤いロゴ領域の境界矩形の比率は異なります。缶の場合は1:1、ビンの場合(キャップ​​の有無)は異なります。これにより、両者を簡単に区別できるはずです。

更新: ロゴ領域の水平方向の曲率は、それぞれのサイズの違いにより、缶とボトルで異なります。これは、ロボットが缶/ボトルを持ち上げる必要があり、それに応じてグリップを決定する場合に特に役立ちます。

于 2018-02-05T19:33:18.830 に答える