Delphi-OpenCV 2.4 テンプレートマッチングを使った角度の検出 2021/03/03


開発環境が Delphi なので、使用している OpenCV のバージョンは 2.4 です。

回転角度の検出は、画像を 360 度回転させるという力業です。
あらかじめ 360 度回転したテンプレート画像を作成する方法ではなく、都度、検索対象の元画像の必要な範囲を回転、切り取り、
基準 0 度のテンプレート画像と比較するという方法です。
速度と精度を上げるために、10 度基準で大まかな角度を検出し、その角度 ±8 度程度を 1 度基準で再検索しています。

これは、開発環境 Delphi で使える OpenCV は 2.4 までで、テンプレートマッチングにマスク画像が使用できないためです。
自前でマスク画像を使える比較関数を作ってみたのですが、遅くて実用できませんでした。

■テンプレート図形を回転させた場合

 OpenCV 2.4 では背景の画像に影響されないように、テンプレート画像は最小の大きさにする必要があります。
 左の画像が基準0度の図形で、右が矩形範囲をそのまま回転させた図形です。
 余白の部分のほうが多くなって、誤認識する可能性が高いことが分かります。
 また、元画像を切り取り、比較するときに余白部分を見越して余分に切り取る必要があります。
  

 回転図形をギリギリの大きさで切り取った場合でも、ある程度の余白が含まれます。
 元画像を切り取り、比較するときは、ギリギリの大きさで切り取ることができます。
 実際には、誤認識を防ぐために周囲に 2 ピクセル程度の背景を含んだテンプレート図形を切り取っています。

 

■元画像を回転させる

 無謀とも言える方法ですが、テンプレート画像を回転させるより、元の画像を回転させ、
 基準 0 度のテンプレート画像と比較するほうが、余計な処理が不要で検出精度が上がります。
 元画像全体を回転するのは時間がかかるので、対象の部分を切り取り、それを回転させています。
 ※OpenCV 3.0 以降のテンプレートマッチングではマスク画像が使えるので、Delphi-OpenCV 2.4 の場合・・・です。

■テンプレートマッチングの高速化

 テンプレートマッチングの速さですが、バイナリ < グレイ < カラー で、バイナリ画像が高速です。
 下のような画像の場合、80msec 程度で完了します。
 うまくバイナリ画像が作成されない場合は、グレイスケール画像での比較になりますが、縦横のサイズを 80% に縮小するだけで、
 1.5 ~2 倍くらい速くなります。精度もそう変わりません。
 縦横のサイズを 1/2 にして、大まかな位置を検出し、それを元に実際の大きさで対象の範囲を切り取り、再度検索すると、
 速度、精度とも良い結果が得られます。

■重なり図形の検出

 ↓58 (78%) の赤枠の中の 3 個の対象物が重なりあっていますが、そのうちの 1 個(右上)が検出でき、重心も取れています。
 (重心はテンプレート図形の重心を当てはめているため、誤差が含まれます。)
  

■グレイスケールでの比較

 混みあった画像の中でも検出可能です。
 

■厚みのある対象物の場合
 ・照明による影の部分も対象物として認識してしまい、重心がずれる。
 ・影の影響で、近接する対象物と繋がってしまう。
 ・・・等、厚みがある対象物には弱いです。

■模様比較

 対象物の中で特徴のある一部分だけを比較すると、背景に影響されません。
 0.7 秒程度で検出。
 

 0.7 秒程度で検出。
 

 誤認識の例
 グレイスケールで比較しているので、QR コードをハートマークと誤認識しています。
 
 
 カラーでの比較だと誤認識が少なります。
 グレイスケール:1.5sec → カラー:2.5sec と時間はかかります。
 

■メッキボルトの検出

 成績が良かったのは、赤い背景で白黒を反転させたバイナリ画像。
 テンプレート画像に赤い背景色を含んでいるので、↓のようにバラバラに置いた時は、検出可能です。
 背景色が変わる、他の対象物と接触して背景色が無くなる場合は、検出できませんでした。

 

 背景が白の場合は、ガンマ値、しきい値を調整してもこの程度↓です。
 右上の接触している2本は合体したひとつの対象物と検出されています。

 

 バックライトを使った場合は、精度が上がります。
 右上の2本には隙間が出来て、1本は検出できています。

 

 接触しあった3本がひとつの対象物として検出されています。
 

 バックライトを使うと、隙間が出来て1本ずつ検出できる確率が上がります。
 バイナリ画像でのテンプレートマッチング(0.08秒)

 


 全体の画像の中から一番一致率の高い位置を探します。
 特徴のある模様の一部を検索することができますが、対象が全体なので時間がかかります。

 グレイスケールでのテンプレートマッチング(0.8秒)

 

 誤認識の例
 確かに緑色の矩形内だけを見ると、ボルトに見えなくもないです。
 一致率 70% 以上とかの制限が必要。