顔認証

ゆうき( @BASEBALLY15 )です^^

前回は,畳み込みニューラルネットワークによって顔の画像を学習しましたね.

そうですね^^

第2章 後半では,学習させた結果を使って,自分の顔と他人の顔を判定します.

はたして,AIは自分の顔と他人の顔を判別することが出来るのでしょうか・・・?

第1章から第3章までの構成要素

ニューラルネットワークによる顔認識の構成要素
(PowerPointで作成)

今回は,第2章の『face_predict.py』を作ります.

前回に,畳み込みニューラルネットワークによって,自分の顔と他人の顔を学習させました.

そこで,この章では,学習させたものとは違う画像をAIが判定できるのかを検証していきます.

AIによる顔判定
(PowerPointで作成)

それでは,コードを見ていきましょう^^

AIは顔を判定できるのか!?

ファイル名:face_predict.py

ライブラリ

#画像を編集するために使う
import cv2

#画像を表示するために使う
import matplotlib.pyplot as plt

#画像を編集するために使う
from PIL import Image

import numpy as np

#コマンドプロンプトから文字を読み取るために使う
import sys

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", "other_face2"]

#表示形式を変えておく
face_name = ["本人です!", "あなたではないです!", "あなたではないです!"]

#クラスの数(=3)
num_face_classes = len(face_classes)

#画像のサイズを指定
image_size = 50

実行した時に,日本語で表示させたいので,『face_name』というクラスを作ります.

次に,画像を判定するために,畳み込みニューラルネットワークのモデルを作ります.

畳み込みニューラルネットワークのモデルを作る!

#ニューラルネットワークのモデルを作成する
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

畳み込みニューラルネットワークのモデルを作ったら,

次に,メインとなる関数を作ります.

メインとなる関数を作ろう!

今回,判定する画像は,顔から体までは映っているため,

そのまま使うと,自分の顔画像を他人の顔だと判定したり,

他人の顔画像を自分だと判定することがあったので,

AIによる顔判定(体全体)
(PowerPointで作成)

第1章で使った,カスケードファイルによって,

顔のみをニューラルネットワークに読み込むと,

上手く判定することが出来ました.

AIによる顔判定(顔のみ)
(PowerPointで作成)

それでは,そのコードをご紹介します.

main_predict()という関数を作ります.

def main_predict():

    #--------------------------------------------------------------------------- 

    #読み込む画像のファイル名
    image_name = str(input("画像ファイル名="))
    
    #入力用にOpenCVで画像を読み込む
    image_in = cv2.imread(image_name)

  #顔の検出器を作成
    face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")

  #グレイスケールに変換
    image_gray = cv2.cvtColor(image_in, cv2.COLOR_BGR2GRAY)

  #顔認証を実行
    face_list = face_cascade.detectMultiScale(image_gray, minNeighbors=20)

    #--------------------------------------------------------------------------- 

    #認証した部分に印をつける(枠で囲む)
    for (x,y,w,h) in face_list:
        
        #赤を用意
        red = (0,0,255)
        #顔の部部を囲む
        cv2.rectangle(image_in, (x,y), (x+w, y+h), red, 1)
        
        #顔の部分のみ取り出す
        trim_face = image_in[y:y+h,x:x+w]
        
        #RGBに変換する(OpenCVのBGRをRGBに変換する)
        image_rgb = cv2.cvtColor(trim_face,cv2.COLOR_BGR2RGB)

    #---------------------------------------------------------------------------

    #OpenCVからpillowに変換
    change_pillow = Image.fromarray(image_rgb)

    #OpenCVのRGBからpillowのRGBに変換する
    image_rgb = change_pillow.convert("RGB")     
        
    #画像のサイズを50×50にリサイズする(顔のみの画像)
    resize_face = image_rgb.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()
    
    #精度を求める
    percentage = int(result[pred]*100)
    
    #結果を表示
    print("\n{0} {1} %".format(face_classes[pred], percentage))
    
    print()

    #["my_face", "other_face", "other_face2"]のどれであるか?
    print(result)

    #---------------------------------------------------------------------------

    #もし,"my_face"なら,
    if face_classes[pred] == "my_face":
    
        print()
        
        #"本人です!"と表示
        print(face_name[pred])
        
    #もし,"other_face"なら,
    elif face_classes[pred] == "other_face":
        
        print()
        
        #"本人ではないです"と表示
        print(face_name[pred])
     
    #もし,"other_face2"なら
    elif face_classes[pred] == "other_face2":
        
        print()
        
        #"本人ではないです"と表示
        print(face_name[pred])

    #---------------------------------------------------------------------------

    #顔のみの画像を表示
    plt.imshow(image_rgb)
    
    plt.show()

    #---------------------------------------------------------------------------

そして,コマンドプロンプトで実行できるように,以下のコードを書きます.

#コマンドプロンプトで実行する          
if __name__ == "__main__":

    #main_predict()を呼びだす
    main_predict()

最後に,Anaconda Promptで実行します.

Anaconda Promptで実行してみよう!

Anaconda Promptを開き,以下の文字を書きます.

  • activate tf140
  • cd Desktop
  • cd face_predict.pyがあるファイル名
  • python face_predict.py

そして,

画像ファイル名=

と聞かれるので,

画像ファイル名=画像ファイル名.jpg

と書くと,このように画像から自分の顔か他人の顔かを判定してくれます.

AIによる判定の結果
(PowerPointで作成)

終わりに

今回は,畳み込みニューラルネットワークによって学習したデータを使って,

本人の顔か他人の顔かを判定してみました.

画像を読み込ませるときに,そのまま読み込ませるのではなく,

顔の部分のみを切り取ることで,正確に判定できることが分かりました.

次回は,第1章から第2章までのファイルを一つにまとめて,実行したいと思います.

それでは・・・

Q &A

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA