目的
ラズパイで撮影した画像を使って、画像の類似度チェックを行いたいと思います。
類似度チェックとは
この記事で行う、類似度チェックとはどういうことかと言いますと。。
まずは、以下のような、リモコンをラズパイで撮影しました。
この向きの状態を基準
とします。
次にリモコンを少し向きを変えた状態のものを、2つ撮影します。
1つ目は真横に傾けたものA
とします
もう一つは基準からほんの少しだけ傾けたものB
とします。
上記の画像AとBで、どちらが基準に近い状態かのチェックを行います。
人間の目でひと目見れば、B
の方が基準の画像に近いです。
これをプログラム上で判断できるようにします。
pythonのOpenCVライブラリを使用すれば、簡単に基準となる画像との類似度を数値化することができます。
判定プログラム
今回は以下のような pythonプログラム(matching.py )を作成しました。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import cv2
# 1.比較元イメージを読み込む
okImage = cv2.imread("./okImage.JPG")
# 2.カメラでの撮影
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
taImage = frame
# 3.比較する
orb = cv2.ORB_create()
kpOk, desOk = orb.detectAndCompute(okImage, None)
kpTa, desTa = orb.detectAndCompute(taImage, None)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(desOk, desTa)
matches = sorted(matches, key = lambda x:x.distance)
dist = [m.distance for m in matches]
# 4.比較結果を出力する
print(sum(dist) / len(dist))
coImage = cv2.drawMatches(okImage,kpOk,taImage,kpTa,matches[:10], None, flags=2)
cv2.imwrite("./coImage.JPG", coImage)
ざっくりの説明ですが、
1.の「okImage.JPG」は
予め撮影していた 基準 となるリモコン画像を指定しておきます。以下の基準画像のことです。
2.では
現在ラズパイのカメラの前にあるリモコン画像を撮影します。
プログラム実行時のリモコンの向き A もしくは B の状態の画像を取得できます。
3.では
OpenCVライブラリを使った比較処理を行っています。
最終的に、比較結果の画像に使われるmatches変数
と類似度を表すdist変数
を求めます。
4.では
プログラム実行後のコンソールに類似値を表示しているのと比較結果の画像をcoImage.JPG
という名前で保存しています。
リモコンを傾けて上記プログラムを実行すると
$ python matching.py
その状態が撮影され、基準のokImage.JPG
と比較します。
まずA
すると、類似値が表示され、比較画像(coImage.JPG)が実行ディレクトリに保存されます。
$ python matching.py
72.73684210526316
比較画像については、基準
とA
が並んでいて、リモコンのいろんな箇所がカラフルな線で結ばれています。
プログラム実行後に表示される数値については、 このカラフル線の長さを図っている ようです。
次にB
今回も類似値が表示され、比較画像(coImage.JPG)が実行ディレクトリに保存されます。
※画像は上書きされるので注意です。
$ python matching.py
37.648648648648646
今回は類似値は37となりました。
A
の72とは2倍違います。
似た画像だと類似値37、似ていない場合は72になるということで、
類似値が小さい方が類似度が高いよう(似ている画像)
となるようです。
先に述べた通り、カラフル線の長さのようなので、類似値が0になることは無いかと。
今回のプログラムを用いると
基準となる画像を用意しておくことで、あるタイミング撮影した画像との類似度を調べる
事ができるようになりました。
今回は以上です。