前提条件
顔の検出と認識を開始する前に、開発環境をセットアップする必要があります。まず、処理を行う前に、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に興味のある上級者や友人の参加へようこそ!