概要
乃木坂46のメンバー(斎藤飛鳥さん、生田絵梨花さん、白石麻衣さんなど)の顔と欅坂46の長濱ねるさんの顔がどれだけ類似しているかを出力するコードを作成しました。
Confidenceが0に近くなれば、似ているということになります。
トレーニングに使用した画像をテストデータとして使用するとConfidenceが0になるので注意です。
トレーニングデータ・テストデータを用意する
PythonでGoogle Custom Search APIを使い画像収集してみた
これを参考に画像のスクレイピングをしてみてください!
類似度を計算するscript
OpenCVで乃木坂46秋元真夏と銀シャリ鰻和弘の類似度を調べてみた
こちらの記事を参考に作成してみました。
similarity.py
import cv2
import os
import numpy as np
from PIL import Image
import re
import os.path
# トレーニング画像
train_path = './train_乃木坂images'
# テスト画像
test_path = './test_images'
# Haar-like特徴分類器
cascadePath = './haarcascade_frontalface_alt.xml'
faceCascade = cv2.CascadeClassifier(cascadePath)
recognizer = cv2.face.LBPHFaceRecognizer_create()
# フォルダ内の画像を習得
def get_images_and_labels(path):
# 画像を格納する配列
images = []
# ラベルを格納する配列
labels = []
for f in os.listdir(path):
# 画像のパス
image_path = os.path.join(path, f)
# 白黒で読み込み
image_pil = Image.open(image_path).convert('L')
# Numpyの配列に格納
image = np.array(image_pil, 'uint8')
# Haar-like特徴分類器で顔を検知
faces = faceCascade.detectMultiScale(image)
# 検出した画像の処理
for(x, y, w, h) in faces:
# 200×200にリサイズ
roi = cv2.resize(image[y: y + h, x: x + w], (200, 200), interpolation=cv2.INTER_LINEAR)
#画像を配列に格納
images.append(roi)
int_number = re.findall("\d+", f)
for number in int_number:
labels.append(int(number))
return images, labels
# トレーニング画像を取得
images, labels = get_images_and_labels(train_path)
# トレーニング実施
recognizer.train(images, np.array(labels))
# テスト画像を取得
test_images, test_labels = get_images_and_labels(test_path)
in_jpg= os.listdir('./test_images')
for i in range(len(in_jpg)):
# テスト画像に対して予測実施
label, confidence = recognizer.predict(test_images[i])
# 予測結果をコンソール出力
print("Confidence: {:.2f}".format(confidence))
次にsimilarity.py
をカメラを起動させて画像を取得し、画面に類似度を出力させるコードも作成してみました。
camera.py
import numpy as np
import cv2
import os
if __name__ == '__main__':
print(" * Loading pre-trained model ...")
cascadePath = './haarcascade_frontalface_alt.xml'
faceCascade = cv2.CascadeClassifier(cascadePath)
recognizer = cv2.face.LBPHFaceRecognizer_create()
# recognizerのloadは次回の記事で触れます
recognizer.read('./sample_model.yml')
print(' * Loading end')
cap = cv2.VideoCapture(0)
# フレームの取得
ret,frame = cap.read()
# 文字のフォント設定
font = cv2.FONT_HERSHEY_PLAIN
# 文字のサイズ設定
font_size = 5
while(True):
ret, frame = cap.read()
if ret == True:
# Webカメラからの画像を白黒画像として読み込み
image_pil = 299/1000 * frame[:, :, 0] + 587/1000 * frame[:, :, 1] + 114/1000 * frame[:, :, 2]
image = np.array(image_pil, 'uint8')
# Haar-like特徴分類器で顔を検知
image1 = faceCascade.detectMultiScale(image)
if len(image1) > 0 :
x, y, w, h = image1[0][0], image1[0][1], image1[0][2], image1[0][3]
# 200×200にリサイズ
image2 = cv2.resize(image[y: y + h, x: x + w],(200, 200), interpolation=cv2.INTER_LINEAR)
# 類似度を予測
label, predict_Confidence = recognizer.predict(image2)
# 類似度を画面に表示
cv2.putText(frame,str(predict_Confidence),(50,700),font,font_size,(255,255,0),4)
cv2.imshow('Show', frame)
#1msecキー入力待ち
cv2.waitKey(1)
else:
break
次回の記事
毎回similarity.py
を実行していると時間がかかるので、次回は、recognizer
をSave
して、Flaskでrecognizer
をLoad
し、類似度をブラウザで出力するAPIを作成してみたいと思います!
参考記事
OpenCVを使って誰の顔なのかを推定する(Eigenface, Fisherface, LBPH)