この記事では、ヒストグラムの類似度を用いたテンプレートマッチングについて詳しく解説します。具体的なコード例も提供しますので、PythonとOpenCVを使用した画像処理に興味がある方はぜひ参考にしてください。
目次
テンプレートマッチングとは
テンプレートマッチング(Template Matching)は、大きな画像(ソース画像)内から特定の小さな画像(テンプレート)がどこに存在するかを探す手法です。これは主にパターン認識やコンピュータビジョンの分野で使用されます。
ヒストグラムとその類似度
ヒストグラムはデータ分布の視覚的表現であり、特定範囲内のデータ項目数を示します。色情報(RGBやHSV等)に対する頻出回数等が一般的です。
ヒストグラム同士の比較(=類似性)計算方法も多く存在し、それらは全て特定状況下で最適化されています。一部代表的な方法ではCorrelation, Chi-Square, Intersection, Bhattacharyya distance等があります。
ヒストグラムを用いたテンプレートマッチング
通常のピクセル値比較型のテンプレートマッチングでは明るさや色の変化に弱いという欠点があります。しかし、ヒストグラムを用いることでこれらの問題をある程度緩和することが可能です。
ソース画像からテンプレートサイズの領域を切り出し、そのヒストグラムをテンプレート画像のヒストグラムと比較します。この比較を全領域で行うことで、最も類似度が高い位置(マッチング位置)を見つけ出すことが可能です。
Python および OpenCV を使った実装例
以下にPythonとOpenCVでヒストグラムの類似度に基づくテンプレートマッチングの実装例を示します。
import cv2 import numpy as np # ソース画像・テンプレート画像読み込み src_img = cv2.imread('source.png') template_img = cv2.imread('template.png') # テンプレート画像のサイズ・ヒストグラム取得 h, w = template_img.shape[:2] hist_template = cv2.calcHist([template_img], [0], None, [256], [0, 256]) # スコア格納用マップ初期化 score_map = np.zeros_like(src_img, dtype=np.float32) # ソース画像内全領域ループ処理 for y in range(src_img.shape[0] - h): for x in range(src_img.shape[1] - w): # 切り出し領域取得 & ヒストグラム計算 roi = src_img[y:y+h, x:x+w] hist_roi = cv2.calcHist([roi], [0], None, [256], [0, 256]) # ヒストグラム比較 (Correlation) score_map[y,x] = cv2.compareHist(hist_template, hist_roi, method=cv2.HISTCMP_CORREL) # 最大スコア位置取得(最もマッチングした場所) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(score_map) print(f"Best matching location : {max_loc}")
このコードはRGB色空間上で1チャンネルだけ使用していますが、HSV等他色空間や多チャンネルに拡張する事も可能です。また、cv2.compareHist
のmethod
引数を変更することで比較方法も自由に選べます。
以上がヒストグラムの類似度を用いたテンプレートマッチングの説明となります。これを応用することで、様々な状況下でも安定したマッチング結果を得ることが可能になります。