しぐれの戯言箱

技術的なメモ書き、ポケモンの調整記事、ソシャゲ奮闘記…etc

python画像処理日記【特徴点マッチングを用いた顔の類似度判定】

はじめに

こんにちは、しぐれです。

突然ですが、僕はアイススケートで有名な羽生結弦選手に似ていると言われることがたまにあります。
自分ではよく分からないので、今回はpythonさんにどれくらい似ているのか確かめてもらおうと思います。


使用した画像

f:id:shiguderika:20191029123725j:plain


実装内容

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の間でした。
(値が小さいほど似ているということになります。)


終わりに

結局、似ているのかよく分からんかった。

今回は画像の特徴点からの測定だったので、次は顔検出した上での測定をやってみたいですね。