Python OpenCVで画像を検索、判定結果を返してみた


背景

画像の一部に、検索したい画像が含まれているかどうかを
判定したい思いにかられたのでやってみました。
元画像の一致した部分を四角で囲んで表示/保存する先例はあったのですが、
判定結果を数値で返す例があまりなかったので、投稿。

こんなイメージ↓↓↓
(左:検索先画像、右:検索したい画像)
(左の画像をトリミングして、右の画像を作っています)

環境

MacOS Mojave ver10.14.4
Anaconda Navigator 1.9.7
 ※Anacondaのインストールは、こちらを参考に
JupiterNotebook 5.4.0
OpenCV 3.4.2
※OpenCVのインストールは以前の記事を参照ください
「初心者がpython Anaconda GUIで、簡単にOpenCVをインストールしてみる」
 https://qiita.com/anzanshi/items/a88df7db49f77f65fbbf

手順

方針

 元画像と、元画像をトリミングした比較画像を部分一致検索をかける!
 最も高い類似度が閾値を超えているかどうかを判定する!
 判定結果を返す

実装

まずは、OpenCVを使うためにライブラリをインポート

import cv2  #OpenCVをインポート

画像の一致率を判定するための関数を設定

def Judge_Matching(num):
    if 0.99 < num:
        return True
    else:
        return False

画像を読み込みんで、画像の一部が含まれているかを検索
※OpenCVのmatchTemplate関数の仕組みはこちらが分かりやすかったです。
※TM_CCORR_NORMEDは、類似度の計算方法の一種。他にも色々あるみたいです。

# 検索元/先画像を読み込み
image = cv2.imread('./imagesFolder/temp/temp_moto.png') #検索先画像のファイルパスを指定
template = cv2.imread('./imagesFolder/temp_template/temp_saki.png') #検索元画像ファイルパスを指定

#OpenCVで画像部分一致を検索
result = cv2.matchTemplate(image, template, cv2.TM_CCORR_NORMED)

# 最も類似度が高い位置と低い位置を取得します
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(result)

#類似度が閾値を超えているか判定(上で作った関数を使用)
Judg = Judge_Matching(maxVal)

#結果を出力
print(Judg)
# (実行結果→)True or False

実行例↓↓↓

終わりに

画像の一部検索の結果を出力することができました。
次は、指定したフォルダ内の複数の画像に対して検索をしてみたいと思います。

参考

http://pynote.hatenablog.com/entry/opencv-template-matching
http://thr3a.hatenablog.com/entry/20150727/1437973061