python画像処理日記【特徴点マッチングを用いた顔の類似度判定】
はじめに
こんにちは、しぐれです。
突然ですが、僕はアイススケートで有名な羽生結弦選手に似ていると言われることがたまにあります。
自分ではよく分からないので、今回はpythonさんにどれくらい似ているのか確かめてもらおうと思います。
使用した画像
実装内容
pyファイルを実行するとカメラが起動。
カメラで画像を撮影し、sample2.jpgとして保存。
(撮影はsキー、終了はqキー、カメラ終了後マッチング判定開始)
羽生選手の画像はsamples.jpgという名前で保存した。
特徴点マッチング判定後、sample2.jpgは削除するようにした。
以下ソースコード
import numpy as np import cv2 import os from PIL import Image import re cap = cv2.VideoCapture(0) while(True): #フレームキャプチャ ret, frame = cap.read() #画面に保存する cv2.imshow('frame',frame) #キーボード入力待ち key = cv2.waitKey(1) & 0xFF #qが押されたら終了 if key == ord('q'): break #sが押されたら保存 if key == ord('s'): path = "sample2.jpg" cv2.imwrite(path,frame) #トレーニング画像 TARGET_FILE = 'samples.jpg' #画像サイズ IMG_SIZE = (200,200) #テスト画像読み込み、グレースケール化? #testname = 'sample2.jpg' target_img = cv2.imread('sample2.jpg',cv2.IMREAD_GRAYSCALE) #リサイズ target_img = cv2.resize(target_img,IMG_SIZE) bf = cv2.BFMatcher(cv2.NORM_HAMMING) # ORBとAKAZEは特徴点や特徴量を抽出するアルゴリズム # コメントアウトを調節することによりどちらでも行える # detector = cv2.ORB_create() detector = cv2.AKAZE_create() #ターゲットの写真の特徴点を取得 (target_kp, target_des) = detector.detectAndCompute(target_img, None) print('TARGET_FILE: %s' % (TARGET_FILE)) #トレーニング画像の読み込み、グレースケール化? comparing_img = cv2.imread('samples.jpg', cv2.IMREAD_GRAYSCALE) comparing_img = cv2.resize(comparing_img, IMG_SIZE) #トレーニング画像の特徴点取得 (comparing_kp, comparimg_des) = detector.detectAndCompute(comparing_img,None) #BFMatcherで総当たりマッチングを行う matches = bf.match(target_des, comparimg_des) #特徴量の距離を出し、平均を取る dist = [m.distance for m in matches] ret = sum(dist) / len(dist) #cv2がエラーの場合 #except cv2.error: #ret = 100000 #結果を出力 print('sample2.jpg', ret) #撮影した画像を削除 os.remove('sample2.jpg')
※cv2がエラーの場合の処理がエラーを起こしているのでとりあえずコメントアウト
画像はpyファイルと同じ場所に格納してるので画像のPATHはありません。
格納場所と実行場所が違う場合等は適宜PATH設定してください。
今回は特徴量を取得するアルゴリズムが2種類用意されており、使い分けることで結果が変わるみたいですね。
出力結果
ApplenoMacBook-Pro:$ python3 ruizido.py TARGET_FILE: samples.jpg sample2.jpg 125.68085106382979
何回かやってみたけど結果は大体123〜129の間でした。
(値が小さいほど似ているということになります。)
終わりに
結局、似ているのかよく分からんかった。
今回は画像の特徴点からの測定だったので、次は顔検出した上での測定をやってみたいですね。