顔の検出と認識にKerasを使用する方法を教えてください

前提条件

顔の検出と認識を開始する前に、開発環境をセットアップする必要があります。まず、処理を行う前に、Pythonを介して画像を「読み取る」必要があります。プロットライブラリmatplotlibを使用して、画像を読み取って操作します。インストーラーから最新バージョンのpipをインストールします。

pip3 install matplotlib

CNNアルゴリズムの実装を使用するには、kerasをインストールする必要があります。次のコマンドを使用して、最新バージョンをダウンロードしてインストールします。

pip3 install keras

次のコマンドを実行して、次の方法でパッケージpipをインストールします。

pip3 install mtcnn

画像から顔を抽出した後、比較のために、オックスフォード大学ビジュアルジオメトリグループによって開発されたVGGFace2アルゴリズムを使用します。VGGアルゴリズムのTensorFlowベースのKeras実装は、以下をインストールするためのソフトウェアパッケージとしてインストールできます。

pip3 install keras_vggface

独自のモデルを構築してトレーニングする必要があるかもしれませんが、膨大なトレーニングデータセットと強力な処理機能が必要です。このチュートリアルはこれらのモデルの実用性に焦点を当てているため、この分野の専門家によって提供された既存のトレーニング済みモデルを使用します。

前提条件が正常にインストールされたので、このチュートリアルに直接進みましょう。

ステップ1:顔検出にMTCNNモデルを使用する

このステップの目標は次のとおりです。

  • ローカルサーバーで外部的にホストされている画像を取得する
  • matplotlibのimread()関数を使用して画像を読み取ります
  • MTCNNアルゴリズムを使用して顔を検出および探索します
  • 画像から顔を抽出します。

多くの人がPythonを学び、どこから始めればよいのかわかりません。
多くの人がPythonを学び、基本的な文法を習得した後、どこから始めればよいかわかりません。
事例研究を行った多くの人々は、より高度な知識を学ぶ方法を知りません。
したがって、これら3つのタイプの人々のために、ビデオチュートリアル、電子書籍、およびコースのソースコードを無料で受け取ることができる優れた学習プラットフォームを提供します。
QQグループ:705933274

1.1外部画像を保存する

多くの場合、外部サーバーでホストされているイメージに基づいて分析できます。この例では、マスタングの父であるリー・アイアコッカがBBCとデトロイトニュースのウェブサイトでホストしている2つの画像を使用します。

分析のために画像を一時的にローカルに保存するために、各画像をそのURLから取得し、ローカルファイルに書き込みます。store_imageの場合、関数を定義します。

import urllib.request
def store_image(url, local_file_name):
  with urllib.request.urlopen(url) as resource:
    with open(local_file_name, 'wb') as f:
      f.write(resource.read())

これで、画像を保存するURLとローカルファイルを使用して関数を呼び出すことができます。

store_image('https://ichef.bbci.co.uk/news/320/cpsprodpb/5944/production/_107725822_55fd57ad-c509-4335-a7d2-bcc86e32be72.jpg',
            'iacocca_1.jpg')
store_image('https://www.gannett-cdn.com/presto/2019/07/03/PDTN/205798e7-9555-4245-99e1-fd300c50ce85-AP_080910055617.jpg?width=540&height=&fit=bounds&auto=webp',
            'iacocca_2.jpg')

画像を正常に取得したら、その中の顔を検出しましょう。

1.2画像内の顔を検出する

このために、2つのインポートを実行します。matplotlibが画像を読み取り、mtcnnが画像内の顔を検出します。

from matplotlib import pyplot as plt
from mtcnn.mtcnn import MTCNN

imread()関数を使用して、画像を読み取ります。

image = plt.imread('iacocca_1.jpg')

次に、MTCNN()オブジェクトを検出器変数として初期化し、.detect_faces()メソッドを使用して画像内の顔を検出します。それが何を返すか見てみましょう:

detector = MTCNN()
faces = detector.detect_faces(image)
for face in faces:
    print(face)

顔ごとに、Python辞書が3つのキーとともに返されます。ボックスキーには、画像内の顔の境界が含まれています。左上の頂点のx座標とy座標、および面を含む長方形の幅と高さの4つの値があります。他の鍵は自信とキーポイントです。キーポイントキーには、検出された顔の特徴とその座標を含む辞書が含まれています。

{'box': [160, 40, 35, 44], 'confidence': 0.9999798536300659, 'keypoints': {'left_eye': (172, 57), 'right_eye': (188, 57), 'nose': (182, 64), 'mouth_left': (173, 73), 'mouth_right': (187, 73)}}

1.3画像内の顔を強調表示する

顔の検出に成功したので、長方形を描画して画像内の顔を強調表示し、検出が正しいことを確認します。

長方形を描画するには、Rectangleオブジェクトmatplotlib.patchesを次の場所からインポートしてください。

from matplotlib.patches import Rectangle

最初に画像を表示し、次に検出された顔に長方形を描画する関数highlight_facesを定義しましょう。まず、画像imread()を読み、imshow()を描画します。検出された顔ごとに、Rectangle()クラスを使用して長方形を描画します。

最後に、.show()メソッドを使用して、画像と長方形を表示します。Jupyterノートブックを使用している場合は、%matplotlibinlinemagicコマンドを使用してプロットをインラインで表示できます。

def highlight_faces(image_path, faces):
  
    image = plt.imread(image_path)
    plt.imshow(image)
    ax = plt.gca()
    
    for face in faces:
        x, y, width, height = face['box']
        face_border = Rectangle((x, y), width, height,
                          fill=False, color='red')
        ax.add_patch(face_border)
    plt.show()

次に、highlight_faces()関数を使用して、画像と検出された顔を表示します。

highlight_faces('iacocca_1.jpg', faces)

リー・アイアコッカの画像で顔が検出されました。出典:BBC

2番目の画像とその中で検出された顔を表示してみましょう。

image = plt.imread('iacocca_2.jpg')
faces = detector.detect_faces(image)
highlight_faces('iacocca_2.jpg', faces)

これらの2つの写真では、MTCNNアルゴリズムが顔を正しく検出していることがわかります。次に、さらに分析するために、画像から顔を抽出してみましょう。

この時点で、検出器から顔の座標を知ることができます。リストインデックスを使用して顔を抽出するのは、かなり簡単な作業です。ただし、使用するVGGFace2アルゴリズムでは、顔のサイズを224 x224ピクセルに調整する必要があります。PILライブラリを使用して画像のサイズを変更します。

関数extract_face_from_image()は、画像からすべての顔を抽出します。

from numpy import asarray
from PIL import Image
def extract_face_from_image(image_path, required_size=(224, 224)):
  
    image = plt.imread(image_path)
    detector = MTCNN()
    faces = detector.detect_faces(image)
    face_images = []
    for face in faces:
        
        x1, y1, width, height = face['box']
        x2, y2 = x1 + width, y1 + height
        
        face_boundary = image[y1:y2, x1:x2]
        
        face_image = Image.fromarray(face_boundary)
        face_image = face_image.resize(required_size)
        face_array = asarray(face_image)
        face_images.append(face_array)
    return face_images
extracted_face = extract_face_from_image('iacocca_1.jpg')
plt.imshow(extracted_face[0])
plt.show()

これは、最初の画像から抽出された顔の外観です。

最初の画像から顔を抽出してサイズを変更します

ステップ2:顔認識にVGGFace2モデルを使用する

このセクションでは、最初に、取得したLeeIacoccaの2つの画像でモデルをテストします。次に、2018年と2019年の上位11人の選手の画像で、チェルシーサッカーチームの顔を比較し続けます。次に、アルゴリズムが画像間の通常のプレーヤーの顔を認識するかどうかを評価できます。

2.12つの顔を比較する

このセクションでは、3つのモジュールをインポートする必要があります。VGGFaceは、顔認識モデルで使用するために抽出する顔を準備し、SciPyから2つの顔の間の距離を計算する余弦関数を作成します。

from keras_vggface.utils import preprocess_input
from keras_vggface.vggface import VGGFace
from scipy.spatial.distance import cosine

抽出された顔を入力として受け取り、計算されたモデルスコアを返す関数を定義しましょう。モデルは、顔の特徴を表すベクトルを返します。

def get_model_scores(faces):
    samples = asarray(faces, 'float32')
    
    samples = preprocess_input(samples, version=2)
    
    model = VGGFace(model='resnet50',
      include_top=False,
      input_shape=(224, 224, 3),
      pooling='avg')
    
    return model.predict(samples)
faces = [extract_face_from_image(image_path)
         for image_path in ['iacocca_1.jpg', 'iacocca_2.jpg']]
model_scores = get_model_scores(faces)

各面のモデルスコアはベクトルであるため、2つの面のスコア間の類似性を見つける必要があります。通常、ユークリッド関数または余弦関数を使用して類似性を計算できます。

顔のベクトル表現は、コサイン類似度に適しています。これは、コサイン距離とユークリッド距離の詳細な比較であり、例を示しています。

cosine()関数は、2つのベクトル間のコサイン距離を計算します。数字が小さいほど、顔のマッチングが良くなります。この例では、しきい値を0.4の距離に配置します。このしきい値は議論する価値があり、ユースケースによって異なります。データセットのケーススタディに基づいて、このしきい値を設定する必要があります。

if cosine(model_scores[0], model_scores[1]) <= 0.4:
  print("Faces Matched")

この場合、リー・アイアコッカの2つの顔が一致しました。

Faces Matched

2.22つの画像の複数の顔を比較する

チュートリアルのこの部分では、モデルを最大限に活用しましょう。2枚の写真で顔を比較します。これらの2枚の写真は、2018-19シーズンのスラビアプラハとのUEFAヨーロッパリーグの試合、チェルシーフットボールクラブの11歳のスタート、リバプールとの2019-20シーズンです。UEFAスーパーカップの試合。両方の試合日にチームには多くのプレーヤーがいますが、アルゴリズムがすべての通常のプレーヤーを検出できるかどうかを見てみましょう。

まず、URLからリソースを取得し、各画像の顔を検出して強調表示します。

store_image('https://cdn.vox-cdn.com/thumbor/Ua2BXGAhneJHLQmLvj-ZzILK-Xs=/0x0:4872x3160/1820x1213/filters:focal(1877x860:2655x1638):format(webp)/cdn.vox-cdn.com/uploads/chorus_image/image/63613936/1143553317.jpg.5.jpg',
            'chelsea_1.jpg')
image = plt.imread('chelsea_1.jpg')
faces_staring_xi = detector.detect_faces(image)
highlight_faces('chelsea_1.jpg', faces_staring_xi)
store_image('https://cdn.vox-cdn.com/thumbor/mT3JHQtZIyInU8_uGxVH-TCbF50=/0x415:5000x2794/1820x1213/filters:focal(1878x1176:2678x1976):format(webp)/cdn.vox-cdn.com/uploads/chorus_image/image/65171515/1161847141.jpg.0.jpg',
            'chelsea_2.jpg')
image = plt.imread('chelsea_2.jpg')
faces = detector.detect_faces(image)
highlight_faces('chelsea_2.jpg', faces)

先に進む前に、2つのゲームのトップ11を次に示します。

  • スラヴィアプラハ大会が始まるXI:ケパ、アズピリクエタ、ルイス、クリステンセン、エマーソン、カンター(カンテ)、バークレー、コバチッチ、デンジャー、ペドロ、ジルー
  • リバプールの11番目のゲームが始まります:コパ、アズピリクタ、クリステンセン、ズマ、エマーソン、カンター、ジョルジニョ、コバック、ペドロ、ジルー、プリシック

XIを開始するために一般的な8人のプレーヤーがあり、理想的にはアルゴリズムと一致する必要があります。

最初にスコアを計算します。

slavia_faces = extract_face_from_image('chelsea_1.jpg')
liverpool_faces = extract_face_from_image('chelsea_2.jpg')
model_scores_starting_xi_slavia = get_model_scores(slavia_faces)
model_scores_starting_xi_liverpool = get_model_scores(liverpool_faces)
``
for idx, face_score_1 in enumerate(model_scores_starting_xi_slavia):
  for idy, face_score_2 in enumerate(model_scores_starting_xi_liverpool):
    score = cosine(face_score_1, face_score_2)
    if score <= 0.4:
      
      print(idx, idy, score)
      
      plt.imshow(slavia_faces[idx])
      plt.show()
      plt.imshow(liverpool_faces[idy])
      plt.show()

これは、アルゴリズムによって一致する2つの面のリストです。8組の顔すべてに一致させることができたことに注意してください。

正しく識別された8つの顔(ケパ、アズピリクエタ、エマーソン、ジルー、カンテ、ペドロ、クリステンセン、コバチッチ)

画像内のすべての顔をうまく一致させることができましたが、一歩下がってスコアの影響について説明したいと思います。前述のように、2つの画像を一致させるための普遍的なしきい値はありません。分析に入力する新しいデータを使用して、これらのしきい値を再定義する必要がある場合があります。たとえば、最適なしきい値のペアをプログラムで決定できない場合、Googleフォトでも入力を受け入れます。

Googleフォトは、顔照合のためのユーザー入力を受け入れます

最良の方法は、さまざまなタイプの顔を照合するときにケースを慎重に評価することです。顔の表情とその角度も精度を決定します。私たちのユースケースでは、プレーヤーがカメラを見つめたときに、最初の11歳の写真を意図的に使用したことに注意してください。最初の11の顔をトロフィーのお祝いの顔と一致させることができますが、精度は低下すると確信しています。

結論として

このチュートリアルでは、最初にMTCNNモデルを使用して画像内の人物の顔を検出し、画像内でそれらを強調表示して、モデルが正しく機能しているかどうかを判断します。次に、VGGFace2アルゴリズムを使用して、ベクトルの形式で顔から特徴を抽出し、異なる顔を照合してそれらを結合します。

自分で作成したPython学習Qグループ:705933274を引き続きお勧めします。グループはすべてPythonを学習しています。Pythonを学習したい、または学習している場合は、ぜひ参加してください。誰もがソフトウェア開発パーティーであり、乾物を共有しています。時々(Pythonソフトウェア開発にのみ関連します)、最新のPythonの高度な資料のコピーや、2021年に自分で編集したゼロベースの教育を含みます。Pythonに興味のある上級者や友人の参加へようこそ!

 

おすすめ

転載: blog.csdn.net/m0_55479420/article/details/115268470