画像内に存在する特定のマークを検出する機会があったので、その際に実践したOpenCVによるパターンマッチングについてまとめていきます。

OpenCVとは

OpenCV (Open Source Computer Vision Library) とは、画像・動画に関する処理機能をまとめたオープンソースのライブラリです。
OpenCVの導入により、画像や動画の中に存在する物体の位置情報やパターン、動きをプログラムが識別できるようになります。

認識した情報を用いて、画像の切り出しや編集も可能となります。
今回はメイン画像とテンプレート画像を渡して、メイン画像内にテンプレート画像が存在するかどうかを検証していきます。
いくつかの検証方法を試したので、以下に結果を記載します。

領域マッチング

まずは、領域マッチング(テンプレートマッチングとも呼ばれる手法)から検証していきます。
これは、対象画像とテンプレート画像をピクセル単位で順次比較して行き、差分が少ない領域を探していく方法です。
今回は一致した領域を赤枠で囲うよう実装をしてみました。


こちらの5名のイラストをメイン画像として使用します


こちらの作業員を検知対象のテンプレート画像として使用し、先ほどの5人の中からこのイラストを探し出してみます。

結果

問題なくテンプレート画像を認識して赤枠で囲うことができました。
今回のような対象画像とテンプレート画像のサイズに差がない場合は高い精度で認識してくれます。また、類似性の閾値も設定することができるのでチューニングも可能です。

問題点

メイン画像内の対象物とテンプレート画像のサイズの差があまりに大きいと、類似度が低いと判断されマッチングしない問題が多々発生します。
閾値をかなり低くしても「一致なし」となってしまったり、見当違いの箇所を一致したと判断するケースが起きてしまいます。
テンプレート画像のサイズや角度が精度に対して大きく影響を与える点には注意が必要です。

特徴量マッチング

次に行ったのは特徴量マッチングと言われる手法です。

比較する2枚の画像のそれぞれに対して「特徴点の抽出」を行い、その特徴点から特徴量を計算し、類似性を比較する方法です。
類似した特徴量を持つキーポイント(特徴点)同士をラインで結ぶことでマッチングの結果を表示します。
テンプレートマッチングと異なり、「特徴点の抽出」には計算が掛かるものの、画像の変形や回転の影響も受けづらいのが特長です。

メイン画像・テンプレート画像ともに先ほどと同じ画像で検証してみましょう。
以下が結果となります。

結果

作業員のイラストの特徴的な部分と認識された箇所が紐づいているのが分かります。この方法ではある程度の角度の違いやサイズの違いには対応できるといったメリットがあるようです。
紐付けしている線の数も好みに変更でき、増やすことでより多くの特徴点を紐づけることが可能となります。

問題点

特徴量マッチング特有の問題点としては、特徴点を検出させたいオブジェクトが画像の端にあると上手く特徴量が計算できないようです。一致させたい要素が画面の端にある場合は注意が必要です。
また、領域マッチングと比較するとサイズや角度の影響は少ないものの、こちらもサイズに大きな差がある場合には特徴点を集中させることは難しい事がわかりました。

領域・特徴点の複合型マッチング

試験的に、上記二つのマッチング方法を組み合わせて検証も行ってみました。
一度領域マッチングをして、マッチした領域を画像として抽出する。
その上で、抽出した画像とテンプレート画像を特徴点マッチングで判定させて、特徴点が一致している箇所を明確にマッチ結果画像として抽出するという方法です。
結果は以下となります。

結果

より詳細なパターンマッチングを行うことができました。
はじめに領域マッチングで類似性が高いと判断された部分を抽出してから特徴点を比較しているので比較結果が明確になっています。
しかし、こちらもメイン画像とテンプレート画像のサイズの差異によって精度が左右される課題は依然として残っているので注意が必要です。

画像内の円形を検出し、円形とテンプレート画像のマッチング

最後に、かなり限定的なマッチング条件になりますが、円形のロゴやマークを検出したい場合の手法を記します。

cv::HoughCircles を使用することで、画像内に存在する円形を検出することができます。
これを用いて画像内に存在する全ての円を抽出してからテンプレート画像と比較し、円の中に検出したい対象と一致するものが存在するかどうかを検証しました。

円領域とテンプレート画像のRGB差分を計算し、色の一致度も算出することで、色の類似度も条件に加える事ができます。
今回の検証では、各円の色の一致度のスコアと領域マッチングの類似度のスコアを合計して、最もスコアの高い画像をベストマッチ画像として抽出できるようにしました。

円形が多く集まっている画像を用意しました。

今回パターンマッチングで認識させたい画像はこちらにします。
結果

結果として、Best Match Circleとして正しく8ボールが検出されました。
緑枠が発生しているボールはある程度一致していると判断されたもので、Best Match Circleが最も類似していたものになります。

特徴の一致度と色の一致度を、それぞれ何対何の割合で重要視するかチューニングすることもできるので、特徴的な色の円形を抽出したい場合は色の比率を高くする事で精度の調整もできます。

今回は特徴5:色5の割合でマッチングを行いました。

問題点

問題なくロゴを検出することができましたが、高い精度で対象物を検出させるためには画像毎に以下の項目のチューニングがおすすめです。
・色の一致度を選別するための閾値の設定(どれくらい色が似ていたら一致とみなすか)
・色と領域マッチングのスコアどちらを重視するかの重りの設定
・検出させる円の精度(どこまで真円に近い円を検出させるか)
これらの項目を画像毎に設定する必要がある点が汎用性に欠けるポイントかなと思いました。

さいごに

今回、様々な手法でパターンマッチングを行ってみました。
メイン画像内の特定したい要素とテンプレート画像のサイズが一致していないといけない点は課題として存在しますが、そこを解決できれば様々なユースケースで活用できる気がしますね。