OpenCV 物体認識

コンピュータビジョンの分野において、物体認識は非常に重要なタスクです。

OpenCVは強力なオープンソースのコンピュータビジョンライブラリであり、物体認識を実現するためのさまざまな方法を提供しています。

本記事では、OpenCVのテンプレートマッチング手法(cv2.matchTemplate())を使用して物体認識を行う方法について詳しく説明します。

テンプレートマッチングとは?

テンプレートマッチングは、画像内で指定されたテンプレート画像に最も類似した領域を探す技術です。

簡単に言うと、テンプレートマッチングとは、大きな画像の中からテンプレート画像(つまり認識したい物体)に最もマッチする部分を探すことです。この方法は、画像内の物体のサイズ、向き、形状がほぼ変わらない場合に適しています。

  • テンプレート画像:対象物体の画像断片。

  • 検索画像:検査対象の画像。

  • マッチング結果:テンプレート画像の検索画像内での類似度分布を表します。

テンプレートマッチングの基本原理

テンプレートマッチングの基本原理は、テンプレート画像をターゲット画像上でスライドさせ、各位置の類似度を計算して、最も類似度の高い位置を見つけることです。OpenCVには、二乗差マッチング(cv2.TM_SQDIFF)、正規化二乗差マッチング(cv2.TM_SQDIFF_NORMED)、相関マッチング(cv2.TM_CCORR)、正規化相関マッチング(cv2.TM_CCORR_NORMED)、相関係数マッチング(cv2.TM_CCOEFF)および正規化相関係数マッチング(cv2.TM_CCOEFF_NORMED)。

応用シーン

  • 物体認識: 画像内で特定の物体(ロゴ、アイコンなど)の位置を特定するために使用します。
  • 物体追跡: 動画内で対象物体を追跡するために使用します。
  • 画像レジストレーション: 2つの画像を位置合わせするために使用します。

テンプレートマッチングの実装手順

  1. 画像の読み込み:検索画像とテンプレート画像を読み取ります。

  2. テンプレートマッチング:使用してcv2.matchTemplate()検索画像内でテンプレート画像を検索します。

  3. マッチング結果の取得:使用してcv2.minMaxLoc()最適なマッチング位置を取得します。

  4. マッチング結果の描画:検索画像内にマッチング領域を描画します。

  5. 結果の表示:マッチング結果を表示します。

マッチング方法

OpenCVは複数のテンプレートマッチング方法を提供しており、cv2.matchTemplate() の3番目のパラメータで指定できます:

方法説明
cv2.TM_SQDIFF二乗差マッチング。値が小さいほどマッチング度が高くなります。
cv2.TM_SQDIFF_NORMED正規化二乗差マッチング。値が小さいほどマッチング度が高くなります。
cv2.TM_CCORR相関マッチング。値が大きいほどマッチング度が高くなります。
cv2.TM_CCORR_NORMED正規化相関マッチング。値が大きいほどマッチング度が高くなります。
cv2.TM_CCOEFF相関係数マッチング。値が大きいほどマッチング度が高くなります。
cv2.TM_CCOEFF_NORMED正規化相関係数マッチング。値が大きいほどマッチング度が高くなります。

使用してcv2.matchTemplate()物体認識を行う

1. 必要なライブラリをインポートする

まず、OpenCV と NumPy ライブラリをインポートする必要があります。

NumPy は Python で科学計算を行うための基礎ライブラリであり、OpenCV は NumPy 配列を使用して画像データを格納します。

例

import cv2
import numpy as np

2. 画像とテンプレートを読み込む

次に、ターゲット画像とテンプレート画像を読み込む必要があります。

ターゲット画像は物体を探すための画像であり、テンプレート画像は認識したい物体です。

例

# ターゲット画像とテンプレート画像を読み込む
img = cv2.imread('target_image.jpg', 0)
template = cv2.imread('template_image.jpg', 0)

3. テンプレート画像のサイズを取得する

ターゲット画像内でテンプレート画像をスライドさせるには、テンプレート画像の幅と高さを知る必要があります。

例

# テンプレート画像のサイズを取得する
w, h = template.shape[::-1]

4. テンプレートマッチングを実行する

使用してcv2.matchTemplate()関数でテンプレートマッチングを実行します。

この関数は結果行列を返します。各要素は、ターゲット画像内の対応する位置とテンプレート画像の類似度を表します。

例

# テンプレートマッチングを実行する
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)

5. マッチング閾値を設定し、マッチング位置を見つける

閾値を設定して、マッチングが成功したかどうかを判断できます。

次に、cv2.minMaxLoc()関数を使用して結果行列内の最大値と最小値の位置を見つけます。

例

# マッチング閾値を設定する
threshold = 0.8

# マッチング位置を見つける
loc = np.where(res >= threshold)

6. ターゲット画像にマッチング位置をマークする

最後に、ターゲット画像内でテンプレートとマッチする位置をマークできます。

通常、矩形の枠を使用してマッチング領域をマークします。

例

# ターゲット画像にマッチング位置をマークする
for pt in zip(*loc[::-1]):
    cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 2)

# 結果画像を表示する
cv2.imshow('Matched Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

完全なコード

以下は、...を使用してcv2.matchTemplate()物体認識を行うための完全なコード例です。

例

import cv2
import numpy as np

# ターゲット画像とテンプレート画像を読み込む
img = cv2.imread('target_image.jpg', 0)
template = cv2.imread('template_image.jpg', 0)

# テンプレート画像のサイズを取得する
w, h = template.shape[::-1]

# テンプレートマッチングを実行する
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)

# マッチング閾値を設定する
threshold = 0.8

# マッチング位置を見つける
loc = np.where(res >= threshold)

# ターゲット画像にマッチング位置をマークする
for pt in zip(*loc[::-1]):
    cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 2)

# 結果画像を表示する
cv2.imshow('Matched Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
その他の拡張