
ゆうき( @BASEBALLY15 )です^^
前回に,畳み込みニューラルネットワークを使って,顔画像から本人か他人かを判定しました.
画像から判定する場合,毎回画像を読み込む必要があり,手間だなと感じていました.
そこで,今回は,映像から,本人か他人かを判定してみました.

目次
AIを使って映像から顔を判定するまでの流れ
1. まずは,本人の顔と他人の顔をカスケードファイルで読み込み,保存します.
2. 保存した顔画像を,学習用とテスト用に分けます.そして,学習用とテスト用に分けたデータを畳み込みニューラルネットワークで学習します.
AIを使って映像から顔を判定してみた!
前回にご紹介した,『顔画像』から本人か他人かを判定する場合は,このように,毎回,画像を読み込ませていました.

これだと,判定したい画像をわざわざ探してきて,本人か他人かを判定する必要があります.
そこで,今回は,このように映像から本人か他人かを判定できるようにしました.

これで,毎回画像を探してくる手間が省けます^^
それでは,コードをご紹介します⤵
ライブラリ
#画像を編集するために使う
import cv2
#画像を編集するために使う
from PIL import Image
import numpy as np
import keras
#ニューラルネットワークのモデルを定義するためのライブラリ
from keras.models import Sequential
#畳み込みの処理やプーリングの処理をするためのライブラリ
from keras.layers import Conv2D, MaxPooling2D
#Activationは活性化関数,Dropoutはドロップアウト処理,
#Flattenはデータを1次元に変換,Denseは全結合
from keras.layers import Activation, Dropout, Flatten, Dense
#ファイルをロードするためのライブラリ
from keras.models import load_model
コード
クラスと画像サイズを決めよう!
まずは,クラスを作成し,ニューラルネットワークで読み込むためのサイズを決めます.
##クラスとクラス数と画像のサイズを指定##
#クラスを作成
face_classes = ["my_face", "other_face"]
#クラスの数(=2)
num_face_classes = len(face_classes)
#画像のサイズを指定(映像から画像にする際のサイズ変更)
width = 500
height = 300
#画像のサイズを指定(ニューラルネットワークで学習するため)
image_size = 50
畳み込みニューラルネットワークのモデルを作成しよう!
#ニューラルネットワークのモデルを作成する
def neural_model():
#------------------------------------------------
model = Sequential()
model.add(Conv2D(32,
kernel_size=(3,3),
padding="same",
input_shape=(image_size, image_size, 3)))
#マイナスの値を除去
model.add(Activation("relu"))
#------------------------------------------------
model.add(Conv2D(32,
kernel_size=(3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
#過学習の抑制(ランダムでニューロンを無効化)
#偏ったニューロンに依存しないため
model.add(Dropout(rate=0.25))#25%無効化
#------------------------------------------------
model.add(Conv2D(64,
kernel_size=(3,3),
padding="same"))
model.add(Activation("relu"))
#------------------------------------------------
model.add(Conv2D(64,
kernel_size=(3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
#------------------------------------------------
model.add(Flatten())
model.add(Dense(512))
model.add(Activation("relu"))
model.add(Dropout(0.5))
model.add(Dense(num_face_classes))
model.add(Activation("softmax"))
#------------------------------------------------
#オプティマイザーを作成
opt = keras.optimizers.RMSprop(learning_rate=0.0001,
decay=1e-6)
#コンパイル
model.compile(loss="categorical_crossentropy",
optimizer=opt,
metrics=["accuracy"])
#モデルのロード
model = load_model("./face_cnn.h5")
return model
(本題)映像から顔を判定しよう!
前回の,画像から顔を判定する方法からの変更点は以下の通りです⤵
- 前回からの変更点1・・・顔が検出された時と,検出されなかった時で場合分けをする
- 前回からの変更点2・・・本人の顔の時は『青色の枠』,他人の顔の時は『赤色の枠』で囲む
(※コード内で,変更点を示しています^^)
def main_predict():
#---------------------------------------------------------------------------
#映像を表示
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
#顔の検出器を作成
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
#---------------------------------------------------------------------------
while True:
ret, frame = cap.read()
#画像にする際のサイズを変更する
frame = cv2.resize(frame,(width, height))
#グレイスケールに変換
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#顔認証を実行
face_list = face_cascade.detectMultiScale(frame_gray, minNeighbors=20)
#---------------------------------------------------------------------------
#前回からの変更点1-ココから-
#---------------------------------------------------------------------------
#もし,顔が検出できなかったら,
if len(face_list) == 0:
#検出できるまで,続ける
continue
#もし,顔が検出できたら,
elif len(face_list) > 0:
#認証した部分に印をつける(枠で囲む)
for (x,y,w,h) in face_list:
#赤を用意
red = (0,0,255)
#顔の部分を囲む
cv2.rectangle(frame, (x,y), (x+w, y+h), red, 1)
#顔の部分のみ取り出す
trim_face = frame[y:y+h,x:x+w]
#RGBに変換する(OpenCVのBGRをRGBに変換する)
image_rgb = cv2.cvtColor(trim_face,cv2.COLOR_BGR2RGB)
#---------------------------------------------------------------------------
#前回からの変更点1-ココまで-
#---------------------------------------------------------------------------
#pillowに変換
change_pillow = Image.fromarray(image_rgb)
#OpenCVのRGBからpillowのRGBに変換する
rgb_pillow = change_pillow.convert("RGB")
#画像のサイズをリサイズする(顔のみの画像)
resize_face = rgb_pillow.resize((image_size, image_size))
#顔の部分のみの画像を数値に変換する
data = np.asarray(resize_face)
#リストを用意
X = []
#Xにdataを入れる
X.append(data)
#XをTensorFlowが扱いやすいようにNumpy型に変換する
X = np.array(X)
#ニューラルネットワークのモデル関数を呼び出す
model = neural_model()
#画像をニューラルネットワークのモデルから予測する
result = model.predict([X])[0]
#一番値の大きい配列の添え字を返す
pred = result.argmax()
#---------------------------------------------------------------------------
#前回からの変更点2-ココから-
#---------------------------------------------------------------------------
#もし,"my_face"なら,
if face_classes[pred] == "my_face":
#映像の顔の部分を青色で囲む
for (x,y,w,h) in face_list:
#青色を準備
blue = (255,0,0)
#顔を枠で囲む
cv2.rectangle(frame, (x, y), (x+w,y+h), blue, 2)
cv2.imshow("Detect_Face", frame)
#もし,Enterキーが押されたら終了する
exit_wind = cv2.waitKey(1)
if exit_wind == 13:
break
#もし,"other_face"なら,
elif face_classes[pred] == "other_face":
#映像の顔の部分を赤色で囲む
for (x,y,w,h) in face_list:
#赤色を準備
red = (0,0,255)
#顔を枠で囲む
cv2.rectangle(frame, (x, y), (x+w,y+h), red, 2)
cv2.imshow("Detect_Face", frame)
#もし,Enterキーが押されたら終了する
exit_wind = cv2.waitKey(1)
if exit_wind == 13:
break
#---------------------------------------------------------------------------
#前回からの変更点2-ココまで-
#---------------------------------------------------------------------------
#Anaconda Prompt上で実行する
if __name__ == "__main__":
main_predict()
Anaconda Prompt上で判定してみよう!
Anaconda Promptを開き,以下の通りに記述すると,AIが顔を判定してくれます.
- activate tf140
- cd Desctop
- python video_face_predict.py
・本人の顔の時

・他人の顔の時

(※顔は隠してありますが,判定は出来ています.)
今後の課題
映像から本人の顔と他人の顔を判定することが出来たけれど,カメラの動きが遅いという問題点があります.
この原因として,映像を畳み込みニューラルネットワークで判定する際に,
映像を1枚ずつ読み込まないといけないからではないかと考えています.
今後は,コードを変更し,カメラの映像をスムーズに動くようにしていきたいです!
終わりに
今回は,AIを使って,映像から本人の顔と他人の顔を判定しました.
無事,判定は出来たけれど,動きが遅いという問題があるので,
改善していきます^^
それでは・・・