クイック スタート:Face クライアント ライブラリを使用する

.NET 用 Face クライアント ライブラリを使用して顔認識を開始します。 以下の手順に従って、パッケージをインストールし、基本タスクのコード例を試してみましょう。 Face サービスは、画像内の人間の顔を検出および認識するための高度なアルゴリズムへのアクセスを提供します。

.NET 用 Face クライアント ライブラリは、次の目的で使用します。

リファレンスのドキュメント | ライブラリのソース コード | パッケージ (NuGet) | サンプル

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します
  • Visual Studio IDE または現在のバージョンの .NET Core
  • Azure サブスクリプションを入手したら、Azure portal で Face リソースを作成し、キーとエンドポイントを取得します。 デプロイされたら、 [リソースに移動] をクリックします。
    • 対象のアプリケーションを Face API に接続するには、作成したリソースのキーとエンドポイントが必要です。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。
    • Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

設定

新しい C# アプリケーションを作成する

Visual Studio を使用して、新しい .NET Core アプリケーションを作成します。

クライアント ライブラリをインストールする

新しいプロジェクトを作成したら、ソリューション エクスプローラー でプロジェクト ソリューションを右クリックし、 [NuGet パッケージの管理] を選択して、クライアント ライブラリをインストールします。 パッケージ マネージャーが開いたら、 [参照] を選択し、 [プレリリースを含める] をオンにして、Microsoft.Azure.CognitiveServices.Vision.Face を検索します。 バージョン 2.7.0-preview.1 を選択し、 [インストール] を選択します。

ヒント

クイックスタートのコード ファイル全体を一度にご覧いただけます。 これは GitHub にあり、このクイックスタートのコード例が含まれています。

プロジェクト ディレクトリから program.cs ファイルを開いて、次の using ディレクティブを追加します。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.Azure.CognitiveServices.Vision.Face;
using Microsoft.Azure.CognitiveServices.Vision.Face.Models;

アプリケーションの Program クラスで、対象のリソースのキーとエンドポイントの変数を作成します。

重要

Azure Portal にアクセスします。 「前提条件」セクションで作成した Face リソースが正常にデプロイされた場合、 [次の手順] の下にある [リソースに移動] ボタンをクリックします。 キーとエンドポイントは、リソースの [key and endpoint](キーとエンドポイント) ページの [リソース管理] にあります。

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、資格情報を安全に格納して利用するための方法を用いることを検討してください。 詳細については、Cognitive Services のセキュリティに関するページを参照してください。

// From your Face subscription in the Azure portal, get your subscription key and endpoint.
const string SUBSCRIPTION_KEY = "PASTE_YOUR_FACE_SUBSCRIPTION_KEY_HERE";
const string ENDPOINT = "PASTE_YOUR_FACE_ENDPOINT_HERE";

アプリケーションの Main メソッドで、このクイックスタートで使用するメソッドの呼び出しを追加します。 これらは後で実装します。

// Authenticate.
IFaceClient client = Authenticate(ENDPOINT, SUBSCRIPTION_KEY);

// Detect - get features from faces.
DetectFaceExtract(client, IMAGE_BASE_URL, RECOGNITION_MODEL4).Wait();
// Find Similar - find a similar face from a list of faces.
FindSimilar(client, IMAGE_BASE_URL, RECOGNITION_MODEL4).Wait();
// Verify - compare two images if the same person or not.
Verify(client, IMAGE_BASE_URL, RECOGNITION_MODEL4).Wait();

// Identify - recognize a face(s) in a person group (a person group is created in this example).
IdentifyInPersonGroup(client, IMAGE_BASE_URL, RECOGNITION_MODEL4).Wait();
// LargePersonGroup - create, then get data.
LargePersonGroup(client, IMAGE_BASE_URL, RECOGNITION_MODEL4).Wait();
// Group faces - automatically group similar faces.
Group(client, IMAGE_BASE_URL, RECOGNITION_MODEL4).Wait();
// FaceList - create a face list, then get data

オブジェクト モデル

以下のクラスとインターフェイスにより、Face .NET クライアント ライブラリの主要な機能の一部が処理されます。

名前 説明
FaceClient このクラスは、Face サービスを使用するための承認を表し、すべての Face 機能に必要です。 サブスクリプション情報を使用してこれをインスタンス化し、他のクラスのインスタンスを生成するために使用します。
FaceOperations このクラスは、人間の顔に対して実行できる基本的な検出と認識のタスクを処理します。
DetectedFace このクラスは、画像内の 1 つの顔から検出されたすべてのデータを表します。 これを使用して、顔に関する詳細情報を取得できます。
FaceListOperations このクラスは、クラウドに格納された FaceList コンストラクトを管理します。これには、さまざまな顔のセットが格納されます。
PersonGroupPersonExtensions このクラスは、クラウドに格納された Person コンストラクトを管理します。これには、1 人の人物に属している顔のセットが格納されます。
PersonGroupOperations このクラスは、クラウドに格納された PersonGroup コンストラクトを管理します。これには、さまざまな Person オブジェクトのセットが格納されます。

コード例

以下のコード スニペットでは、.NET 用 Face クライアント ライブラリを使用して次のタスクを実行する方法を示しています。

クライアントを認証する

新しいメソッドで、実際のエンドポイントとキーを使用してクライアントをインスタンス化します。 自分のキーを指定して ApiKeyServiceClientCredentials オブジェクトを作成し、それを自分のエンドポイントと共に使用して FaceClient オブジェクトを作成します。

/*
 *	AUTHENTICATE
 *	Uses subscription key and region to create a client.
 */
public static IFaceClient Authenticate(string endpoint, string key)
{
    return new FaceClient(new ApiKeyServiceClientCredentials(key)) { Endpoint = endpoint };
}

ヘルパー フィールドを宣言する

次のフィールドは、後で追加するいくつかの Face 操作に必要です。 Program クラスのルートで、次の URL 文字列を定義します。 この URL は、サンプル画像のフォルダーを指しています。

// Used for all examples.
// URL for the images.
const string IMAGE_BASE_URL = "https://csdx.blob.core.windows.net/resources/Face/Images/";

Main メソッドで、さまざまな認識モデルの種類を指すように文字列を定義します。 後で、顔検出に使用する認識モデルを指定できます。 それらの選択については、認識モデルの指定に関するページを参照してください。

// Recognition model 4 was released in 2021 February.
// It is recommended since its accuracy is improved
// on faces wearing masks compared with model 3,
// and its overall accuracy is improved compared
// with models 1 and 2.
const string RECOGNITION_MODEL4 = RecognitionModel.Recognition04;

画像内の顔を検出する

検出された顔オブジェクトを取得する

顔を検出するための新しいメソッドを作成します。 DetectFaceExtract メソッドでは、指定された URL にある画像のうち 3 つを処理し、 DetectedFace オブジェクトのリストをプログラムのメモリに作成します。 抽出する特徴は、 FaceAttributeType 値のリストで指定します。

/* 
 * DETECT FACES
 * Detects features from faces and IDs them.
 */
public static async Task DetectFaceExtract(IFaceClient client, string url, string recognitionModel)
{
    Console.WriteLine("========DETECT FACES========");
    Console.WriteLine();

    // Create a list of images
    List<string> imageFileNames = new List<string>
                    {
                        "detection1.jpg",    // single female with glasses
                        // "detection2.jpg", // (optional: single man)
                        // "detection3.jpg", // (optional: single male construction worker)
                        // "detection4.jpg", // (optional: 3 people at cafe, 1 is blurred)
                        "detection5.jpg",    // family, woman child man
                        "detection6.jpg"     // elderly couple, male female
                    };

    foreach (var imageFileName in imageFileNames)
    {
        IList<DetectedFace> detectedFaces;

        // Detect faces with all attributes from image url.
        detectedFaces = await client.Face.DetectWithUrlAsync($"{url}{imageFileName}",
                returnFaceAttributes: new List<FaceAttributeType> { FaceAttributeType.Accessories, FaceAttributeType.Age,
                FaceAttributeType.Blur, FaceAttributeType.Emotion, FaceAttributeType.Exposure, FaceAttributeType.FacialHair,
                FaceAttributeType.Gender, FaceAttributeType.Glasses, FaceAttributeType.Hair, FaceAttributeType.HeadPose,
                FaceAttributeType.Makeup, FaceAttributeType.Noise, FaceAttributeType.Occlusion, FaceAttributeType.Smile },
                // We specify detection model 1 because we are retrieving attributes.
                detectionModel: DetectionModel.Detection01,
                recognitionModel: recognitionModel);

        Console.WriteLine($"{detectedFaces.Count} face(s) detected from image `{imageFileName}`.");

ヒント

また、ローカルの画像から顔を検出することもできます。 IFaceOperations のメソッドを参照してください (DetectWithStreamAsync など)。

検出された顔データを表示する

DetectFaceExtract メソッドの残りの部分では、検出された各顔の属性データが解析されて出力されます。 各属性は、元の顔検出 API 呼び出しで個別に指定する必要があります ( FaceAttributeType リストで)。 次のコードではすべての属性が処理されますが、通常、使用する必要があるのは 1 個または数個だけです。

        // Parse and print all attributes of each detected face.
        foreach (var face in detectedFaces)
        {
            Console.WriteLine($"Face attributes for {imageFileName}:");

            // Get bounding box of the faces
            Console.WriteLine($"Rectangle(Left/Top/Width/Height) : {face.FaceRectangle.Left} {face.FaceRectangle.Top} {face.FaceRectangle.Width} {face.FaceRectangle.Height}");

            // Get accessories of the faces
            List<Accessory> accessoriesList = (List<Accessory>)face.FaceAttributes.Accessories;
            int count = face.FaceAttributes.Accessories.Count;
            string accessory; string[] accessoryArray = new string[count];
            if (count == 0) { accessory = "NoAccessories"; }
            else
            {
                for (int i = 0; i < count; ++i) { accessoryArray[i] = accessoriesList[i].Type.ToString(); }
                accessory = string.Join(",", accessoryArray);
            }
            Console.WriteLine($"Accessories : {accessory}");

            // Get face other attributes
            Console.WriteLine($"Age : {face.FaceAttributes.Age}");
            Console.WriteLine($"Blur : {face.FaceAttributes.Blur.BlurLevel}");

            // Get emotion on the face
            string emotionType = string.Empty;
            double emotionValue = 0.0;
            Emotion emotion = face.FaceAttributes.Emotion;
            if (emotion.Anger > emotionValue) { emotionValue = emotion.Anger; emotionType = "Anger"; }
            if (emotion.Contempt > emotionValue) { emotionValue = emotion.Contempt; emotionType = "Contempt"; }
            if (emotion.Disgust > emotionValue) { emotionValue = emotion.Disgust; emotionType = "Disgust"; }
            if (emotion.Fear > emotionValue) { emotionValue = emotion.Fear; emotionType = "Fear"; }
            if (emotion.Happiness > emotionValue) { emotionValue = emotion.Happiness; emotionType = "Happiness"; }
            if (emotion.Neutral > emotionValue) { emotionValue = emotion.Neutral; emotionType = "Neutral"; }
            if (emotion.Sadness > emotionValue) { emotionValue = emotion.Sadness; emotionType = "Sadness"; }
            if (emotion.Surprise > emotionValue) { emotionType = "Surprise"; }
            Console.WriteLine($"Emotion : {emotionType}");

            // Get more face attributes
            Console.WriteLine($"Exposure : {face.FaceAttributes.Exposure.ExposureLevel}");
            Console.WriteLine($"FacialHair : {string.Format("{0}", face.FaceAttributes.FacialHair.Moustache + face.FaceAttributes.FacialHair.Beard + face.FaceAttributes.FacialHair.Sideburns > 0 ? "Yes" : "No")}");
            Console.WriteLine($"Gender : {face.FaceAttributes.Gender}");
            Console.WriteLine($"Glasses : {face.FaceAttributes.Glasses}");

            // Get hair color
            Hair hair = face.FaceAttributes.Hair;
            string color = null;
            if (hair.HairColor.Count == 0) { if (hair.Invisible) { color = "Invisible"; } else { color = "Bald"; } }
            HairColorType returnColor = HairColorType.Unknown;
            double maxConfidence = 0.0f;
            foreach (HairColor hairColor in hair.HairColor)
            {
                if (hairColor.Confidence <= maxConfidence) { continue; }
                maxConfidence = hairColor.Confidence; returnColor = hairColor.Color; color = returnColor.ToString();
            }
            Console.WriteLine($"Hair : {color}");

            // Get more attributes
            Console.WriteLine($"HeadPose : {string.Format("Pitch: {0}, Roll: {1}, Yaw: {2}", Math.Round(face.FaceAttributes.HeadPose.Pitch, 2), Math.Round(face.FaceAttributes.HeadPose.Roll, 2), Math.Round(face.FaceAttributes.HeadPose.Yaw, 2))}");
            Console.WriteLine($"Makeup : {string.Format("{0}", (face.FaceAttributes.Makeup.EyeMakeup || face.FaceAttributes.Makeup.LipMakeup) ? "Yes" : "No")}");
            Console.WriteLine($"Noise : {face.FaceAttributes.Noise.NoiseLevel}");
            Console.WriteLine($"Occlusion : {string.Format("EyeOccluded: {0}", face.FaceAttributes.Occlusion.EyeOccluded ? "Yes" : "No")} " +
                $" {string.Format("ForeheadOccluded: {0}", face.FaceAttributes.Occlusion.ForeheadOccluded ? "Yes" : "No")}   {string.Format("MouthOccluded: {0}", face.FaceAttributes.Occlusion.MouthOccluded ? "Yes" : "No")}");
            Console.WriteLine($"Smile : {face.FaceAttributes.Smile}");
            Console.WriteLine();
        }
    }
}

似た顔の検索

以下のコードでは、検出された顔 (ソース) を 1 つ受け取って、他の顔のセット (ターゲット) から一致するものを見つけます (画像による顔検索)。 一致するものが見つかると、一致した顔の ID がコンソールに出力されます。

比較の対象となる顔を検出する

まず、2 つ目の顔検出メソッドを定義します。 顔を比較するためにはまず、画像で顔を検出する必要があります。また、この検出メソッドは比較操作向けに最適化されています。 前のセクションほど詳細には顔の属性を抽出せず、また、別の認識モデルを使用しています。

private static async Task<List<DetectedFace>> DetectFaceRecognize(IFaceClient faceClient, string url, string recognition_model)
{
    // Detect faces from image URL. Since only recognizing, use the recognition model 1.
    // We use detection model 3 because we are not retrieving attributes.
    IList<DetectedFace> detectedFaces = await faceClient.Face.DetectWithUrlAsync(url, recognitionModel: recognition_model, detectionModel: DetectionModel.Detection03);
    Console.WriteLine($"{detectedFaces.Count} face(s) detected from image `{Path.GetFileName(url)}`");
    return detectedFaces.ToList();
}

一致するものを探す

次のメソッドでは、一連のターゲット画像と単一のソース画像から顔を検出します。 その後、それらを比較し、ソース画像と似ているターゲット画像をすべて見つけます。

/*
 * FIND SIMILAR
 * This example will take an image and find a similar one to it in another image.
 */
public static async Task FindSimilar(IFaceClient client, string url, string recognition_model)
{
    Console.WriteLine("========FIND SIMILAR========");
    Console.WriteLine();

    List<string> targetImageFileNames = new List<string>
                        {
                            "Family1-Dad1.jpg",
                            "Family1-Daughter1.jpg",
                            "Family1-Mom1.jpg",
                            "Family1-Son1.jpg",
                            "Family2-Lady1.jpg",
                            "Family2-Man1.jpg",
                            "Family3-Lady1.jpg",
                            "Family3-Man1.jpg"
                        };

    string sourceImageFileName = "findsimilar.jpg";
    IList<Guid?> targetFaceIds = new List<Guid?>();
    foreach (var targetImageFileName in targetImageFileNames)
    {
        // Detect faces from target image url.
        var faces = await DetectFaceRecognize(client, $"{url}{targetImageFileName}", recognition_model);
        // Add detected faceId to list of GUIDs.
        targetFaceIds.Add(faces[0].FaceId.Value);
    }

    // Detect faces from source image url.
    IList<DetectedFace> detectedFaces = await DetectFaceRecognize(client, $"{url}{sourceImageFileName}", recognition_model);
    Console.WriteLine();

    // Find a similar face(s) in the list of IDs. Comapring only the first in list for testing purposes.
    IList<SimilarFace> similarResults = await client.Face.FindSimilarAsync(detectedFaces[0].FaceId.Value, null, null, targetFaceIds);

次のコードは、一致の詳細をコンソールに出力します。

foreach (var similarResult in similarResults)
{
    Console.WriteLine($"Faces from {sourceImageFileName} & ID:{similarResult.FaceId} are similar with confidence: {similarResult.Confidence}.");
}
Console.WriteLine();

顔を識別する

識別操作では、人物 (1人または複数人) の画像を受け取り、その画像に含まれるそれぞれの顔の同一性を見つけます (顔認識検索)。 検出された顔はそれぞれ、顔の特徴が確認されているさまざまな Person オブジェクトのデータベース、つまり PersonGroup と比較されます。 識別操作を行うには、最初に PersonGroup を作成してトレーニングする必要があります

PersonGroup を作成する

次のコードでは、6 つの異なる Person オブジェクトを含んだ PersonGroup を作成します。 各 Person を一連のサンプル画像に関連付け、顔の特徴によって各人物を認識するためのトレーニングを行います。 Person オブジェクトと PersonGroup オブジェクトは、検証、識別、グループ化の各操作で使用されます。

作成する PersonGroup の ID を表す文字列変数をクラスのルートで宣言します。

static string personGroupId = Guid.NewGuid().ToString();

新しいメソッドに次のコードを追加します。 このメソッドは、識別操作を実行します。 コードの最初のブロックでは、人物の名前をそのサンプル画像に関連付けます。

public static async Task IdentifyInPersonGroup(IFaceClient client, string url, string recognitionModel)
{
    Console.WriteLine("========IDENTIFY FACES========");
    Console.WriteLine();

    // Create a dictionary for all your images, grouping similar ones under the same key.
    Dictionary<string, string[]> personDictionary =
        new Dictionary<string, string[]>
            { { "Family1-Dad", new[] { "Family1-Dad1.jpg", "Family1-Dad2.jpg" } },
              { "Family1-Mom", new[] { "Family1-Mom1.jpg", "Family1-Mom2.jpg" } },
              { "Family1-Son", new[] { "Family1-Son1.jpg", "Family1-Son2.jpg" } },
              { "Family1-Daughter", new[] { "Family1-Daughter1.jpg", "Family1-Daughter2.jpg" } },
              { "Family2-Lady", new[] { "Family2-Lady1.jpg", "Family2-Lady2.jpg" } },
              { "Family2-Man", new[] { "Family2-Man1.jpg", "Family2-Man2.jpg" } }
            };
    // A group photo that includes some of the persons you seek to identify from your dictionary.
    string sourceImageFileName = "identification1.jpg";

このコードでは変数 sourceImageFileName が定義されていることに注意してください。 この変数は、ソース画像 (識別の対象となる人物を含んだ画像) に対応します。

次に、Dictionary 内の人物ごとに Person オブジェクトを作成して該当する画像から顔データを追加する次のコードを追加します。 各 Person オブジェクトは、その一意の ID 文字列によって同じ PersonGroup に関連付けられます。 このメソッドに clienturlRECOGNITION_MODEL1 の各変数を忘れずに渡してください。

// Create a person group. 
Console.WriteLine($"Create a person group ({personGroupId}).");
await client.PersonGroup.CreateAsync(personGroupId, personGroupId, recognitionModel: recognitionModel);
// The similar faces will be grouped into a single person group person.
foreach (var groupedFace in personDictionary.Keys)
{
    // Limit TPS
    await Task.Delay(250);
    Person person = await client.PersonGroupPerson.CreateAsync(personGroupId: personGroupId, name: groupedFace);
    Console.WriteLine($"Create a person group person '{groupedFace}'.");

    // Add face to the person group person.
    foreach (var similarImage in personDictionary[groupedFace])
    {
        Console.WriteLine($"Add face to the person group person({groupedFace}) from image `{similarImage}`");
        PersistedFace face = await client.PersonGroupPerson.AddFaceFromUrlAsync(personGroupId, person.PersonId,
            $"{url}{similarImage}", similarImage);
    }
}

ヒント

ローカル画像から PersonGroup を作成することもできます。 IPersonGroupPerson のメソッドを参照してください (AddFaceFromStreamAsync など)。

PersonGroup をトレーニングする

画像から顔データを抽出して個別の Person オブジェクトに分類したら、各 Person オブジェクトに関連付けられた視覚的特徴を識別できるよう PersonGroup をトレーニングする必要があります。 次のコードは、非同期の train メソッドを呼び出し、結果をポーリングして、状態をコンソールに出力します。

// Start to train the person group.
Console.WriteLine();
Console.WriteLine($"Train person group {personGroupId}.");
await client.PersonGroup.TrainAsync(personGroupId);

// Wait until the training is completed.
while (true)
{
    await Task.Delay(1000);
    var trainingStatus = await client.PersonGroup.GetTrainingStatusAsync(personGroupId);
    Console.WriteLine($"Training status: {trainingStatus.Status}.");
    if (trainingStatus.Status == TrainingStatusType.Succeeded) { break; }
}
Console.WriteLine();

ヒント

Face API は、本質的に静的な一連の事前構築済みモデルで実行されます (サービスの実行中にモデルのパフォーマンスが低下したり改善されたりすることはありません)。 Microsoft により、まったく新しいモデル バージョンに移行することなくモデルのバックエンドが更新されると、モデルによって生成される結果が変わる可能性があります。 より新しいバージョンのモデルを利用するには、同じ登録画像でより新しいモデルをパラメーターとして指定し、PersonGroup を再トレーニングすることができます。

これで、この Person グループとそれに関連付けられた Person オブジェクトを検証、識別、グループ化の各操作で使用する準備が整いました。

顔を識別する

次のコードは、ソース画像を受け取って、その画像で検出されたすべての顔のリストを作成します。 それらの顔が、PersonGroup と照らして識別されることになります。

List<Guid> sourceFaceIds = new List<Guid>();
// Detect faces from source image url.
List<DetectedFace> detectedFaces = await DetectFaceRecognize(client, $"{url}{sourceImageFileName}", recognitionModel);

// Add detected faceId to sourceFaceIds.
foreach (var detectedFace in detectedFaces) { sourceFaceIds.Add(detectedFace.FaceId.Value); }

次のコード スニペットは、IdentifyAsync 操作を呼び出してその結果をコンソールに出力します。 ここでは、このサービスによって、ソース画像に含まれるそれぞれの顔が、指定された PersonGroup 内の Person と照合されます。 これにより、識別メソッドが終了します。

    // Identify the faces in a person group. 
    var identifyResults = await client.Face.IdentifyAsync(sourceFaceIds, personGroupId);

    foreach (var identifyResult in identifyResults)
    {
        Person person = await client.PersonGroupPerson.GetAsync(personGroupId, identifyResult.Candidates[0].PersonId);
        Console.WriteLine($"Person '{person.Name}' is identified for face in: {sourceImageFileName} - {identifyResult.FaceId}," +
            $" confidence: {identifyResult.Candidates[0].Confidence}.");
    }
    Console.WriteLine();
}

アプリケーションの実行

IDE ウィンドウの上部にある [デバッグ] ボタンをクリックして、アプリケーションを実行します。

リソースをクリーンアップする

Cognitive Services サブスクリプションをクリーンアップして削除したい場合は、リソースまたはリソース グループを削除することができます。 リソース グループを削除すると、それに関連付けられている他のリソースも削除されます。

このクイックスタートで作成してある PersonGroup を削除したい場合は、プログラムで次のコードを実行します。

// At end, delete person groups in both regions (since testing only)
Console.WriteLine("========DELETE PERSON GROUP========");
Console.WriteLine();
DeletePersonGroup(client, personGroupId).Wait();

次のコードを使用して削除メソッドを定義します。

/*
 * DELETE PERSON GROUP
 * After this entire example is executed, delete the person group in your Azure account,
 * otherwise you cannot recreate one with the same name (if running example repeatedly).
 */
public static async Task DeletePersonGroup(IFaceClient client, String personGroupId)
{
    await client.PersonGroup.DeleteAsync(personGroupId);
    Console.WriteLine($"Deleted the person group {personGroupId}.");
}

次のステップ

このクイックスタートでは、.NET 用の Face クライアント ライブラリを使用して基本的な顔認識タスクを行う方法について学習しました。 次に、さまざまな顔検出モデルと、ユース ケースに適したモデルを指定する方法について学習します。

Go 用 Face クライアント ライブラリを使用して顔認識を開始します。 以下の手順に従って、パッケージをインストールし、基本タスクのコード例を試してみましょう。 Face サービスは、画像内の人間の顔を検出および認識するための高度なアルゴリズムへのアクセスを提供します。

Go 用 Face サービス クライアント ライブラリは、次の目的で使用します。

リファレンス ドキュメント | ライブラリのソース コード | SDK のダウンロード

前提条件

  • 最新バージョンの Go
  • Azure サブスクリプション - 無料アカウントを作成します
  • Azure サブスクリプションを入手したら、Azure portal で Face リソースを作成し、キーとエンドポイントを取得します。 デプロイされたら、 [リソースに移動] をクリックします。
    • 対象のアプリケーションを Face API に接続するには、作成したリソースのキーとエンドポイントが必要です。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。
    • Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。
  • キーとエンドポイントを取得したら、キーとエンドポイントの環境変数を作成し、それぞれ FACE_SUBSCRIPTION_KEY および FACE_ENDPOINT という名前を付けます。

設定

Go プロジェクト ディレクトリを作成する

コンソール ウィンドウ (cmd、PowerShell、ターミナル、Bash) で、Go プロジェクト用に my-app という名前の新しいワークスペースを作成し、そこに移動します。

mkdir -p my-app/{src, bin, pkg}  
cd my-app

ワークスペースには次の 3 つのフォルダーが格納されます。

  • src - このディレクトリには、ソース コードとパッケージが格納されます。 go get コマンドを使用してインストールされるパッケージはすべてこのフォルダーに入ります。
  • pkg - このディレクトリには、コンパイル済みの Go パッケージ オブジェクトが格納されます。 これらのファイルにはいずれも .a という拡張子が付きます。
  • bin - このディレクトリには、go install を実行するときに作成されたバイナリ実行可能ファイルが格納されます。

ヒント

Go ワークスペースの構造の詳細については、Go 言語のドキュメントを参照してください。 このガイドには、$GOPATH$GOROOT の設定に関する情報が記載されています。

Go 用クライアント ライブラリをインストールする

次に、Go 用クライアント ライブラリをインストールします。

go get -u github.com/Azure/azure-sdk-for-go/tree/master/services/cognitiveservices/v1.0/face

または、dep を使用している場合は、リポジトリ内で次を実行します。

dep ensure -add https://github.com/Azure/azure-sdk-for-go/tree/master/services/cognitiveservices/v1.0/face

Go アプリケーションを作成する

次に、src ディレクトリに sample-app.go という名前のファイルを作成します。

cd src
touch sample-app.go

普段使用している IDE またはテキスト エディターで sample-app.go を開きます。 次に、パッケージの名前を追加し、次のライブラリをインポートします。

package main

import (
    "encoding/json"
    "container/list"
    "context"
    "fmt"
    "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/v1.0/face"
    "github.com/Azure/go-autorest/autorest"
    "github.com/satori/go.uuid"
    "io"
    "io/ioutil"
    "log"
    "os"
    "path"
    "strconv"
    "strings"
    "time"
)

次に、さまざまな Face サービス操作を実行するコードの追加を開始します。

オブジェクト モデル

以下のクラスとインターフェイスにより、Face サービス Go クライアント ライブラリの主要な機能の一部が処理されます。

名前 説明
BaseClient このクラスは、Face サービスを使用するための承認を表し、すべての Face 機能に必要です。 サブスクリプション情報を使用してこれをインスタンス化し、他のクラスのインスタンスを生成するために使用します。
Client このクラスは、人間の顔に対して実行できる基本的な検出と認識のタスクを処理します。
DetectedFace このクラスは、画像内の 1 つの顔から検出されたすべてのデータを表します。 これを使用して、顔に関する詳細情報を取得できます。
ListClient このクラスは、クラウドに格納された FaceList コンストラクトを管理します。これには、さまざまな顔のセットが格納されます。
PersonGroupPersonClient このクラスは、クラウドに格納された Person コンストラクトを管理します。これには、1 人の人物に属している顔のセットが格納されます。
PersonGroupClient このクラスは、クラウドに格納された PersonGroup コンストラクトを管理します。これには、さまざまな Person オブジェクトのセットが格納されます。
SnapshotClient このクラスは、スナップショット機能を管理します。 これを使用すると、クラウドベースのすべての Face データを一時的に保存し、そのデータを新しい Azure サブスクリプションに移行することができます。

コード例

これらのコード サンプルは、Go 用 Face サービス クライアント ライブラリを使用して基本的なタスクを実行する方法を示しています。

クライアントを認証する

注意

このクイックスタートでは、それぞれ FACE_SUBSCRIPTION_KEY および FACE_ENDPOINT という名前の、Face キーとエンドポイントの環境変数を作成してあることを前提としています。

main 関数を作成し、その関数に次のコードを追加して、エンドポイントとキーでクライアントをインスタンス化します。 キーを使用して CognitiveServicesAuthorizer オブジェクトを作成し、それをエンドポイントと共に使用して、 Client オブジェクトを作成します。 また、このコードでは、クライアント オブジェクトの作成に必要なコンテキスト オブジェクトをインスタンス化します。 さらに、このクイックスタートのいくつかのサンプル画像があるリモートの場所を定義しています。

func main() {

    // A global context for use in all samples
    faceContext := context.Background()

    // Base url for the Verify and Large Face List examples
    const imageBaseURL = "https://csdx.blob.core.windows.net/resources/Face/Images/"

    /*
    Authenticate
    */
    // Add FACE_SUBSCRIPTION_KEY, FACE_ENDPOINT, and AZURE_SUBSCRIPTION_ID to your environment variables.
    subscriptionKey := os.Getenv("FACE_SUBSCRIPTION_KEY")
    endpoint := os.Getenv("FACE_ENDPOINT")

    // Client used for Detect Faces, Find Similar, and Verify examples.
    client := face.NewClient(endpoint)
    client.Authorizer = autorest.NewCognitiveServicesAuthorizer(subscriptionKey)
    /*
    END - Authenticate
    */

画像内の顔を検出する

main メソッド内に次のコードを追加します。 このコードは、リモートのサンプル画像を定義し、画像から抽出する顔の特徴を指定します。 また、検出された顔からどの AI モデルを使用してデータを抽出するかも指定しています。 それらの選択については、認識モデルの指定に関するページを参照してください。 最後に、 DetectWithURL メソッドで画像に対する顔検出処理を実行し、その結果をプログラムのメモリに保存します。

// Detect a face in an image that contains a single face
singleFaceImageURL := "https://www.biography.com/.image/t_share/MTQ1MzAyNzYzOTgxNTE0NTEz/john-f-kennedy---mini-biography.jpg" 
singleImageURL := face.ImageURL { URL: &singleFaceImageURL } 
singleImageName := path.Base(singleFaceImageURL)
// Array types chosen for the attributes of Face
attributes := []face.AttributeType {"age", "emotion", "gender"}
returnFaceID := true
returnRecognitionModel := false
returnFaceLandmarks := false

// API call to detect faces in single-faced image, using recognition model 4
// We specify detection model 1 because we are retrieving attributes.
detectSingleFaces, dErr := client.DetectWithURL(faceContext, singleImageURL, &returnFaceID, &returnFaceLandmarks, attributes, face.Recognition04, &returnRecognitionModel, face.Detection01)
if dErr != nil { log.Fatal(dErr) }

// Dereference *[]DetectedFace, in order to loop through it.
dFaces := *detectSingleFaces.Value

ヒント

また、ローカルの画像から顔を検出することもできます。 Client のメソッドを参照してください (DetectWithStream など)。

検出された顔データを表示する

次のコード ブロックでは、 DetectedFace オブジェクトの配列の最初の要素を取得し、その属性をコンソールに出力します。 複数の顔が写った画像を使用する場合は、配列を反復処理することになります。

fmt.Println("Detected face in (" + singleImageName + ") with ID(s): ")
fmt.Println(dFaces[0].FaceID)
fmt.Println()
// Find/display the age and gender attributes
for _, dFace := range dFaces { 
    fmt.Println("Face attributes:")
    fmt.Printf("  Age: %.0f", *dFace.FaceAttributes.Age) 
    fmt.Println("\n  Gender: " + dFace.FaceAttributes.Gender) 
} 
// Get/display the emotion attribute
emotionStruct := *dFaces[0].FaceAttributes.Emotion
// Convert struct to a map
var emotionMap map[string]float64
result, _ := json.Marshal(emotionStruct)
json.Unmarshal(result, &emotionMap)
// Find the emotion with the highest score (confidence level). Range is 0.0 - 1.0.
var highest float64 
emotion := ""
dScore := -1.0
for name, value := range emotionMap{
    if (value > highest) {
        emotion, dScore = name, value
        highest = value
    }
}
fmt.Println("  Emotion: " + emotion + " (score: " + strconv.FormatFloat(dScore, 'f', 3, 64) + ")")

似た顔の検索

以下のコードでは、検出された顔 (ソース) を 1 つ受け取って、他の顔のセット (ターゲット) から一致するものを見つけます (画像による顔検索)。 一致するものが見つかると、一致した顔の ID がコンソールに出力されます。

比較の対象となる顔を検出する

まず、「画像内の顔を検出する」セクションで検出した顔の参照を保存します。 この顔がソースになります。

// Select an ID in single-faced image for comparison to faces detected in group image. Used in Find Similar.
firstImageFaceID := dFaces[0].FaceID

さらに、別の画像から一連の顔を検出する次のコードを入力します。 これらの顔がターゲットになります。

// Detect the faces in an image that contains multiple faces
groupImageURL := "http://www.historyplace.com/kennedy/president-family-portrait-closeup.jpg"
groupImageName := path.Base(groupImageURL)
groupImage := face.ImageURL { URL: &groupImageURL } 

// API call to detect faces in group image, using recognition model 4. This returns a ListDetectedFace struct.
// We specify detection model 3 because we are not retrieving attributes.
detectedGroupFaces, dgErr := client.DetectWithURL(faceContext, groupImage, &returnFaceID, &returnFaceLandmarks, nil, face.Recognition04, &returnRecognitionModel, face.Detection03)
if dgErr != nil { log.Fatal(dgErr) }
fmt.Println()

// Detect faces in the group image.
// Dereference *[]DetectedFace, in order to loop through it.
dFaces2 := *detectedGroupFaces.Value
// Make slice list of UUIDs
faceIDs := make([]uuid.UUID, len(dFaces2))
fmt.Print("Detected faces in (" + groupImageName + ") with ID(s):\n")
for i, face := range dFaces2 {
    faceIDs[i] = *face.FaceID // Dereference DetectedFace.FaceID
    fmt.Println(*face.FaceID)
}

一致するものを探す

次のコードでは、 FindSimilar メソッドを使用して、ソースの顔と一致するターゲットの顔をすべて検索します。

// Add single-faced image ID to struct
findSimilarBody := face.FindSimilarRequest { FaceID: firstImageFaceID, FaceIds: &faceIDs }
// Get the list of similar faces found in the group image of previously detected faces
listSimilarFaces, sErr := client.FindSimilar(faceContext, findSimilarBody)
if sErr != nil { log.Fatal(sErr) }

// The *[]SimilarFace 
simFaces := *listSimilarFaces.Value

次のコードは、一致の詳細をコンソールに出力します。

// Print the details of the similar faces detected 
fmt.Print("Similar faces found in (" + groupImageName + ") with ID(s):\n")
var sScore float64
for _, face := range simFaces {
    fmt.Println(face.FaceID)
    // Confidence of the found face with range 0.0 to 1.0.
    sScore = *face.Confidence
    fmt.Println("The similarity confidence: ", strconv.FormatFloat(sScore, 'f', 3, 64))
}

PersonGroup を作成してトレーニングする

このシナリオの手順を実行するには、プロジェクトのルート ディレクトリに画像 (https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/Face/images ) を保存する必要があります。

この画像のグループには、3 人の異なる人物に対応する 3 種類の顔画像が含まれています。写真には、1 枚につき 1 人の顔が写っています。 このコードでは、3 つの PersonGroup Person オブジェクトを定義し、それらを womanman、および child で始まる画像ファイルに関連付けます。

PersonGroup を作成する

画像をダウンロードしたら、main メソッドの一番下に次のコードを追加します。 このコードは、 PersonGroupClient オブジェクトを認証し、それを使用して新しい PersonGroup を定義します。

// Get working directory
root, rootErr := os.Getwd()
if rootErr != nil { log.Fatal(rootErr) }

// Full path to images folder
imagePathRoot := path.Join(root+"\\images\\")

// Authenticate - Need a special person group client for your person group
personGroupClient := face.NewPersonGroupClient(endpoint)
personGroupClient.Authorizer = autorest.NewCognitiveServicesAuthorizer(subscriptionKey)

// Create the Person Group
// Create an empty Person Group. Person Group ID must be lower case, alphanumeric, and/or with '-', '_'.
personGroupID := "unique-person-group"
fmt.Println("Person group ID: " + personGroupID)
metadata := face.MetaDataContract { Name: &personGroupID }

// Create the person group
personGroupClient.Create(faceContext, personGroupID, metadata)

PersonGroup Person を作成する

次のコード ブロックでは、 PersonGroupPersonClient を認証し、それを使用して、新しい PersonGroup Person オブジェクトを 3 つ定義します。 これらのオブジェクトはそれぞれ、一連の画像に含まれる 1 人の人物を表します。

// Authenticate - Need a special person group person client for your person group person
personGroupPersonClient := face.NewPersonGroupPersonClient(endpoint)
personGroupPersonClient.Authorizer = autorest.NewCognitiveServicesAuthorizer(subscriptionKey)

// Create each person group person for each group of images (woman, man, child)
// Define woman friend
w := "Woman"
nameWoman := face.NameAndUserDataContract { Name: &w }
// Returns a Person type
womanPerson, wErr := personGroupPersonClient.Create(faceContext, personGroupID, nameWoman)
if wErr != nil { log.Fatal(wErr) }
fmt.Print("Woman person ID: ")
fmt.Println(womanPerson.PersonID)
// Define man friend
m := "Man"
nameMan := face.NameAndUserDataContract { Name: &m }
// Returns a Person type
manPerson, wErr := personGroupPersonClient.Create(faceContext, personGroupID, nameMan)
if wErr != nil { log.Fatal(wErr) }
fmt.Print("Man person ID: ")
fmt.Println(manPerson.PersonID)
// Define child friend
ch := "Child"
nameChild := face.NameAndUserDataContract { Name: &ch }
// Returns a Person type
childPerson, wErr := personGroupPersonClient.Create(faceContext, personGroupID, nameChild)
if wErr != nil { log.Fatal(wErr) }
fmt.Print("Child person ID: ")
fmt.Println(childPerson.PersonID)

顔を人物に割り当てる

次のコードは、画像をそのプレフィックスで並べ替えて顔を検出し、画像ファイルの名前に基づいて、それぞれ個別の PersonGroup Person オブジェクトに割り当てます。

// Detect faces and register to correct person
// Lists to hold all their person images
womanImages := list.New()
manImages := list.New()
childImages := list.New()

// Collect the local images for each person, add them to their own person group person
images, fErr := ioutil.ReadDir(imagePathRoot)
if fErr != nil { log.Fatal(fErr)}
for _, f := range images {
    path:= (imagePathRoot+f.Name())
    if strings.HasPrefix(f.Name(), "w") {
        var wfile io.ReadCloser
        wfile, err:= os.Open(path)
        if err != nil { log.Fatal(err) }
        womanImages.PushBack(wfile)
        personGroupPersonClient.AddFaceFromStream(faceContext, personGroupID, *womanPerson.PersonID, wfile, "", nil, face.Detection03)
    }
    if strings.HasPrefix(f.Name(), "m") {
        var mfile io.ReadCloser
        mfile, err:= os.Open(path)
        if err != nil { log.Fatal(err) }
        manImages.PushBack(mfile)
        personGroupPersonClient.AddFaceFromStream(faceContext, personGroupID, *manPerson.PersonID, mfile, "", nil, face.Detection03)
    }
    if strings.HasPrefix(f.Name(), "ch") {
        var chfile io.ReadCloser
        chfile, err:= os.Open(path)
        if err != nil { log.Fatal(err) }
        childImages.PushBack(chfile)
        personGroupPersonClient.AddFaceFromStream(faceContext, personGroupID, *childPerson.PersonID, chfile, "", nil, face.Detection03)
    }
}

ヒント

URL によって参照されたリモート画像から PersonGroup を作成することもできます。 PersonGroupPersonClient のメソッドを参照してください (AddFaceFromURL など)。

PersonGroup をトレーニングする

顔を割り当てたら、PersonGroup をトレーニングして、その各 Person オブジェクトに関連付けられている視覚的特徴を識別できるようにします。 次のコードは、非同期の train メソッドを呼び出し、結果をポーリングして、状態をコンソールに出力します。

// Train the person group
personGroupClient.Train(faceContext, personGroupID)

// Wait for it to succeed in training
for {
    trainingStatus, tErr := personGroupClient.GetTrainingStatus(faceContext, personGroupID)
    if tErr != nil { log.Fatal(tErr) }
    
    if trainingStatus.Status == "succeeded" {
        fmt.Println("Training status:", trainingStatus.Status)
        break
    }
    time.Sleep(2)
}

ヒント

Face API は、本質的に静的な一連の事前構築済みモデルで実行されます (サービスの実行中にモデルのパフォーマンスが低下したり改善されたりすることはありません)。 Microsoft により、まったく新しいモデル バージョンに移行することなくモデルのバックエンドが更新されると、モデルによって生成される結果が変わる可能性があります。 より新しいバージョンのモデルを利用するには、同じ登録画像でより新しいモデルをパラメーターとして指定し、PersonGroup を再トレーニングすることができます。

顔を識別する

識別操作では、人物 (1人または複数人) の画像を受け取り、その画像に含まれるそれぞれの顔の同一性を見つけます (顔認識検索)。 検出された顔はそれぞれ、顔の特徴が確認されているさまざまな Person オブジェクトのデータベース、つまり PersonGroup と比較されます。

重要

この例を実行するには、まず、「PersonGroup を作成してトレーニングする」のコードを実行する必要があります。

テスト画像を取得する

次のコードは、プロジェクトのルートから画像 test-image-person-group.jpg を探して、プログラムのメモリに読み込みます。 この画像は、「PersonGroup を作成してトレーニングする」で使用した画像と同じリポジトリにあります (https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/Face/images )。

personGroupTestImageName := "test-image-person-group.jpg"
// Use image path root from the one created in person group
personGroupTestImagePath := imagePathRoot
var personGroupTestImage io.ReadCloser
// Returns a ReaderCloser
personGroupTestImage, identErr:= os.Open(personGroupTestImagePath+personGroupTestImageName)
if identErr != nil { log.Fatal(identErr) }

テスト画像からソースの顔を検出する

次のコード ブロックでは、テスト画像に通常の顔検出を実行してすべての顔を取得し、それらを配列に保存します。

// Detect faces in group test image, using recognition model 1 (default)
returnIdentifyFaceID := true
// Returns a ListDetectedFaces
// Recognition04 is not compatible.
// We specify detection model 3 because we are not retrieving attributes.
detectedTestImageFaces, dErr := client.DetectWithStream(faceContext, personGroupTestImage, &returnIdentifyFaceID, nil, nil, face.Recognition01, nil, face.Detection03)
if dErr != nil { log.Fatal(dErr) }

// Make list of face IDs from the detection. 
length := len(*detectedTestImageFaces.Value)
testImageFaceIDs := make([]uuid.UUID, length)
// ListDetectedFace is a struct with a Value property that returns a *[]DetectedFace
for i, f := range *detectedTestImageFaces.Value {
    testImageFaceIDs[i] = *f.FaceID
}

顔を識別する

Identify メソッドは、検出された顔の配列を受け取って、指定された PersonGroup (前セクションで定義、トレーニングしたもの) と比較します。 検出された顔がグループ内の Person と一致する場合は、結果を保存します。

// Identify the faces in the test image with everyone in the person group as a query
identifyRequestBody := face.IdentifyRequest { FaceIds: &testImageFaceIDs, PersonGroupID: &personGroupID }
identifiedFaces, err := client.Identify(faceContext, identifyRequestBody)
if err != nil { log.Fatal(err) }

その後、詳細な一致結果をコンソールに出力します。

// Get the result which person(s) were identified
iFaces := *identifiedFaces.Value
for _, person := range iFaces {
    fmt.Println("Person for face ID: " )
    fmt.Print(person.FaceID)
    fmt.Println(" is identified in " + personGroupTestImageName + ".")
}

顔を確認する

確認操作では、顔 ID と、別の顔 ID または Person オブジェクトのいずれかを取得し、同じ人に属しているかどうかを判断します。

次のコードでは、2 つのソース画像から顔を検出し、それぞれターゲット画像から検出された顔と照らして確認します。

テスト イメージを取得する

次のコード ブロックでは、確認操作のターゲット画像とソース画像を指す変数を宣言します。

// Create a slice list to hold the target photos of the same person
targetImageFileNames :=  make([]string, 2)
targetImageFileNames[0] = "Family1-Dad1.jpg"
targetImageFileNames[1] = "Family1-Dad2.jpg"

// The source photos contain this person, maybe
sourceImageFileName1 := "Family1-Dad3.jpg"
sourceImageFileName2 := "Family1-Son1.jpg"

確認対象の顔を検出する

次のコードは、ソース画像とターゲット画像から顔を検出して、それらを変数に保存します。

// DetectWithURL parameters
urlSource1 := imageBaseURL + sourceImageFileName1
urlSource2 := imageBaseURL + sourceImageFileName2
url1 :=  face.ImageURL { URL: &urlSource1 }
url2 := face.ImageURL { URL: &urlSource2 }
returnFaceIDVerify := true
returnFaceLandmarksVerify := false
returnRecognitionModelVerify := false

// Detect face(s) from source image 1, returns a ListDetectedFace struct
// We specify detection model 3 because we are not retrieving attributes.
detectedVerifyFaces1, dErrV1 := client.DetectWithURL(faceContext, url1 , &returnFaceIDVerify, &returnFaceLandmarksVerify, nil, face.Recognition04, &returnRecognitionModelVerify, face.Detection03)
if dErrV1 != nil { log.Fatal(dErrV1) }
// Dereference the result, before getting the ID
dVFaceIds1 := *detectedVerifyFaces1.Value 
// Get ID of the detected face
imageSource1Id := dVFaceIds1[0].FaceID
fmt.Println(fmt.Sprintf("%v face(s) detected from image: %v", len(dVFaceIds1), sourceImageFileName1))

// Detect face(s) from source image 2, returns a ListDetectedFace struct
// We specify detection model 3 because we are not retrieving attributes.
detectedVerifyFaces2, dErrV2 := client.DetectWithURL(faceContext, url2 , &returnFaceIDVerify, &returnFaceLandmarksVerify, nil, face.Recognition04, &returnRecognitionModelVerify, face.Detection03)
if dErrV2 != nil { log.Fatal(dErrV2) }
// Dereference the result, before getting the ID
dVFaceIds2 := *detectedVerifyFaces2.Value 
// Get ID of the detected face
imageSource2Id := dVFaceIds2[0].FaceID
fmt.Println(fmt.Sprintf("%v face(s) detected from image: %v", len(dVFaceIds2), sourceImageFileName2))
// Detect faces from each target image url in list. DetectWithURL returns a VerifyResult with Value of list[DetectedFaces]
// Empty slice list for the target face IDs (UUIDs)
var detectedVerifyFacesIds [2]uuid.UUID
for i, imageFileName := range targetImageFileNames {
    urlSource := imageBaseURL + imageFileName 
    url :=  face.ImageURL { URL: &urlSource}
    // We specify detection model 3 because we are not retrieving attributes.
    detectedVerifyFaces, dErrV := client.DetectWithURL(faceContext, url, &returnFaceIDVerify, &returnFaceLandmarksVerify, nil, face.Recognition04, &returnRecognitionModelVerify, face.Detection03)
    if dErrV != nil { log.Fatal(dErrV) }
    // Dereference *[]DetectedFace from Value in order to loop through it.
    dVFaces := *detectedVerifyFaces.Value
    // Add the returned face's face ID
    detectedVerifyFacesIds[i] = *dVFaces[0].FaceID
    fmt.Println(fmt.Sprintf("%v face(s) detected from image: %v", len(dVFaces), imageFileName))
}

確認の結果を取得する

次のコードでは、各ソース画像をターゲット画像と比較し、同じ人物のものであるかどうかを示すメッセージを出力します。

// Verification example for faces of the same person. The higher the confidence, the more identical the faces in the images are.
// Since target faces are the same person, in this example, we can use the 1st ID in the detectedVerifyFacesIds list to compare.
verifyRequestBody1 := face.VerifyFaceToFaceRequest{ FaceID1: imageSource1Id, FaceID2: &detectedVerifyFacesIds[0] }
verifyResultSame, vErrSame := client.VerifyFaceToFace(faceContext, verifyRequestBody1)
if vErrSame != nil { log.Fatal(vErrSame) }

fmt.Println()

// Check if the faces are from the same person.
if (*verifyResultSame.IsIdentical) {
    fmt.Println(fmt.Sprintf("Faces from %v & %v are of the same person, with confidence %v", 
    sourceImageFileName1, targetImageFileNames[0], strconv.FormatFloat(*verifyResultSame.Confidence, 'f', 3, 64)))
} else {
    // Low confidence means they are more differant than same.
    fmt.Println(fmt.Sprintf("Faces from %v & %v are of a different person, with confidence %v", 
    sourceImageFileName1, targetImageFileNames[0], strconv.FormatFloat(*verifyResultSame.Confidence, 'f', 3, 64)))
}

// Verification example for faces of different persons. 
// Since target faces are same person, in this example, we can use the 1st ID in the detectedVerifyFacesIds list to compare.
verifyRequestBody2 := face.VerifyFaceToFaceRequest{ FaceID1: imageSource2Id, FaceID2: &detectedVerifyFacesIds[0] }
verifyResultDiff, vErrDiff := client.VerifyFaceToFace(faceContext, verifyRequestBody2)
if vErrDiff != nil { log.Fatal(vErrDiff) }
// Check if the faces are from the same person.
if (*verifyResultDiff.IsIdentical) {
    fmt.Println(fmt.Sprintf("Faces from %v & %v are of the same person, with confidence %v", 
    sourceImageFileName2, targetImageFileNames[0], strconv.FormatFloat(*verifyResultDiff.Confidence, 'f', 3, 64)))
} else {
    // Low confidence means they are more differant than same.
    fmt.Println(fmt.Sprintf("Faces from %v & %v are of a different person, with confidence %v", 
    sourceImageFileName2, targetImageFileNames[0], strconv.FormatFloat(*verifyResultDiff.Confidence, 'f', 3, 64)))
}

アプリケーションの実行

go run <app-name> コマンドを使用して、アプリケーション ディレクトリから顔認識アプリを実行します。

go run sample-app.go

リソースをクリーンアップする

Cognitive Services サブスクリプションをクリーンアップして削除したい場合は、リソースまたはリソース グループを削除することができます。 リソース グループを削除すると、それに関連付けられている他のリソースも削除されます。

このクイックスタートで作成した PersonGroup を削除したい場合は、 Delete メソッドを呼び出します。

次のステップ

このクイックスタートでは、Go 用の Face クライアント ライブラリを使用して基本的な顔認識タスクを行う方法について学習しました。 次に、さまざまな顔検出モデルと、ユース ケースに適したモデルを指定する方法について学習します。

クイック スタート: JavaScript 用 Face クライアント ライブラリ

JavaScript 用 Face クライアント ライブラリを使用して顔認識を開始します。 以下の手順に従って、パッケージをインストールし、基本タスクのコード例を試してみましょう。 Face サービスは、画像内の人間の顔を検出および認識するための高度なアルゴリズムへのアクセスを提供します。

JavaScript 用 Face クライアント ライブラリは、次の目的で使用します。

リファレンスのドキュメント | ライブラリのソース コード | パッケージ (npm) | サンプル

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します
  • 最新バージョンの Node.js
  • Azure サブスクリプションを入手したら、Azure portal で Face リソースを作成して、キーとエンドポイントを取得します。 デプロイされたら、 [リソースに移動] をクリックします。
    • 対象のアプリケーションを Face API に接続するには、作成したリソースのキーとエンドポイントが必要です。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。
    • Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

設定

新しい Node.js アプリケーションを作成する

コンソール ウィンドウ (cmd、PowerShell、Bash など) で、ご利用のアプリ用に新しいディレクトリを作成し、そこに移動します。

mkdir myapp && cd myapp

npm init コマンドを実行し、package.json ファイルを使用して node アプリケーションを作成します。

npm init

クライアント ライブラリをインストールする

ms-rest-azure および azure-cognitiveservices-face NPM パッケージをインストールします。

npm install @azure/cognitiveservices-face @azure/ms-rest-js

アプリの package.json ファイルが依存関係によって更新されます。

index.js という名前のファイルを作成して次のライブラリをインポートします。

ヒント

クイックスタートのコード ファイル全体を一度にご覧いただけます。 これは GitHub にあり、このクイックスタートのコード例が含まれています。

const msRest = require("@azure/ms-rest-js");
const Face = require("@azure/cognitiveservices-face");
const uuid = require("uuid/v4");

自分のリソースの Azure エンドポイントおよびキー用の変数を作成します。

重要

Azure Portal にアクセスします。 「前提条件」セクションで作成した Face リソースが正常にデプロイされた場合、 [次の手順] の下にある [リソースに移動] ボタンをクリックします。 キーとエンドポイントは、リソースの [key and endpoint](キーとエンドポイント) ページの [リソース管理] にあります。

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、資格情報を安全に格納して利用するための方法を用いることを検討してください。 詳細については、Cognitive Services のセキュリティに関するページを参照してください。

key = "<paste-your-face-key-here>"
endpoint = "<paste-your-face-endpoint-here>"

オブジェクト モデル

以下のクラスとインターフェイスにより、Face .NET クライアント ライブラリの主要な機能の一部が処理されます。

名前 説明
FaceClient このクラスは、Face サービスを使用するための承認を表し、すべての Face 機能に必要です。 サブスクリプション情報を使用してこれをインスタンス化し、他のクラスのインスタンスを生成するために使用します。
Face このクラスは、人間の顔に対して実行できる基本的な検出と認識のタスクを処理します。
DetectedFace このクラスは、画像内の 1 つの顔から検出されたすべてのデータを表します。 これを使用して、顔に関する詳細情報を取得できます。
FaceList このクラスは、クラウドに格納された FaceList コンストラクトを管理します。これには、さまざまな顔のセットが格納されます。
PersonGroupPerson このクラスは、クラウドに格納された Person コンストラクトを管理します。これには、1 人の人物に属している顔のセットが格納されます。
PersonGroup このクラスは、クラウドに格納された PersonGroup コンストラクトを管理します。これには、さまざまな Person オブジェクトのセットが格納されます。

コード例

以下のコード スニペットでは、.NET 用 Face クライアント ライブラリを使用して次のタスクを実行する方法を示しています。

ヒント

クイックスタートのコード ファイル全体を一度にご覧いただけます。 これは GitHub にあり、このクイックスタートのコード例が含まれています。

クライアントを認証する

ご利用のエンドポイントとキーを使用してクライアントをインスタンス化します。 自分のキーを指定して ApiKeyCredentials オブジェクトを作成し、それを自分のエンドポイントと共に使用して FaceClient オブジェクトを作成します。

const credentials = new msRest.ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': key } });
const client = new Face.FaceClient(credentials, endpoint);

グローバル値とヘルパー関数を宣言する

次のグローバル値は、後で追加する Face 操作のいくつかに必要です。

URL は、サンプル画像のフォルダーを指しています。 UUID は、作成する PersonGroup の名前と ID の両方として機能します。

const image_base_url = "https://csdx.blob.core.windows.net/resources/Face/Images/";
const person_group_id = uuid();

次の関数を使用して、PersonGroup のトレーニングの完了を待ちます。

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

画像内の顔を検出する

検出された顔オブジェクトを取得する

顔を検出するための新しいメソッドを作成します。 DetectFaceExtract メソッドでは、指定された URL にある画像のうち 3 つを処理し、 DetectedFace オブジェクトのリストをプログラムのメモリに作成します。 抽出する特徴は、 FaceAttributeType 値のリストで指定します。

その後、DetectFaceExtract メソッドにより、検出された各顔の属性データが解析され、出力されます。 各属性は、元の顔検出 API 呼び出しで個別に指定する必要があります ( FaceAttributeType リストで)。 次のコードではすべての属性が処理されますが、通常、使用する必要があるのは 1 個または数個だけです。

async function DetectFaceExtract() {
    console.log("========DETECT FACES========");
    console.log();

    // Create a list of images
    const image_file_names = [
        "detection1.jpg",    // single female with glasses
        // "detection2.jpg", // (optional: single man)
        // "detection3.jpg", // (optional: single male construction worker)
        // "detection4.jpg", // (optional: 3 people at cafe, 1 is blurred)
        "detection5.jpg",    // family, woman child man
        "detection6.jpg"     // elderly couple, male female
    ];

// NOTE await does not work properly in for, forEach, and while loops. Use Array.map and Promise.all instead.
    await Promise.all (image_file_names.map (async function (image_file_name) {
        let detected_faces = await client.face.detectWithUrl(image_base_url + image_file_name,
            {
                returnFaceAttributes: ["Accessories","Age","Blur","Emotion","Exposure","FacialHair","Gender","Glasses","Hair","HeadPose","Makeup","Noise","Occlusion","Smile"],
                // We specify detection model 1 because we are retrieving attributes.
                detectionModel: "detection_01"
            });
        console.log (detected_faces.length + " face(s) detected from image " + image_file_name + ".");
        console.log("Face attributes for face(s) in " + image_file_name + ":");

// Parse and print all attributes of each detected face.
        detected_faces.forEach (async function (face) {
            // Get the bounding box of the face
            console.log("Bounding box:\n  Left: " + face.faceRectangle.left + "\n  Top: " + face.faceRectangle.top + "\n  Width: " + face.faceRectangle.width + "\n  Height: " + face.faceRectangle.height);

            // Get the accessories of the face
            let accessories = face.faceAttributes.accessories.join();
            if (0 === accessories.length) {
                console.log ("No accessories detected.");
            }
            else {
                console.log ("Accessories: " + accessories);
            }

            // Get face other attributes
            console.log("Age: " + face.faceAttributes.age);
            console.log("Blur: " + face.faceAttributes.blur.blurLevel);

            // Get emotion on the face
            let emotions = "";
            let emotion_threshold = 0.0;
            if (face.faceAttributes.emotion.anger > emotion_threshold) { emotions += "anger, "; }
            if (face.faceAttributes.emotion.contempt > emotion_threshold) { emotions += "contempt, "; }
            if (face.faceAttributes.emotion.disgust > emotion_threshold) { emotions +=  "disgust, "; }
            if (face.faceAttributes.emotion.fear > emotion_threshold) { emotions +=  "fear, "; }
            if (face.faceAttributes.emotion.happiness > emotion_threshold) { emotions +=  "happiness, "; }
            if (face.faceAttributes.emotion.neutral > emotion_threshold) { emotions +=  "neutral, "; }
            if (face.faceAttributes.emotion.sadness > emotion_threshold) { emotions +=  "sadness, "; }
            if (face.faceAttributes.emotion.surprise > emotion_threshold) { emotions +=  "surprise, "; }
            if (emotions.length > 0) {
                console.log ("Emotions: " + emotions.slice (0, -2));
            }
            else {
                console.log ("No emotions detected.");
            }
            
            // Get more face attributes
            console.log("Exposure: " + face.faceAttributes.exposure.exposureLevel);
            if (face.faceAttributes.facialHair.moustache + face.faceAttributes.facialHair.beard + face.faceAttributes.facialHair.sideburns > 0) {
                console.log("FacialHair: Yes");
            }
            else {
                console.log("FacialHair: No");
            }
            console.log("Gender: " + face.faceAttributes.gender);
            console.log("Glasses: " + face.faceAttributes.glasses);

            // Get hair color
            var color = "";
            if (face.faceAttributes.hair.hairColor.length === 0) {
                if (face.faceAttributes.hair.invisible) { color = "Invisible"; } else { color = "Bald"; }
            }
            else {
                color = "Unknown";
                var highest_confidence = 0.0;
                face.faceAttributes.hair.hairColor.forEach (function (hair_color) {
                    if (hair_color.confidence > highest_confidence) {
                        highest_confidence = hair_color.confidence;
                        color = hair_color.color;
                    }
                });
            }
            console.log("Hair: " + color);

            // Get more attributes
            console.log("Head pose:");
            console.log("  Pitch: " + face.faceAttributes.headPose.pitch);
            console.log("  Roll: " + face.faceAttributes.headPose.roll);
            console.log("  Yaw: " + face.faceAttributes.headPose.yaw);
 
            console.log("Makeup: " + ((face.faceAttributes.makeup.eyeMakeup || face.faceAttributes.makeup.lipMakeup) ? "Yes" : "No"));
            console.log("Noise: " + face.faceAttributes.noise.noiseLevel);

            console.log("Occlusion:");
            console.log("  Eye occluded: " + (face.faceAttributes.occlusion.eyeOccluded ? "Yes" : "No"));
            console.log("  Forehead occluded: " + (face.faceAttributes.occlusion.foreheadOccluded ? "Yes" : "No"));
            console.log("  Mouth occluded: " + (face.faceAttributes.occlusion.mouthOccluded ? "Yes" : "No"));

            console.log("Smile: " + face.faceAttributes.smile);
            console.log();
        });
    }));
}

ヒント

また、ローカルの画像から顔を検出することもできます。 DetectWithStreamAsync などの Face メソッドを参照してください。

似た顔の検索

以下のコードでは、検出された顔 (ソース) を 1 つ受け取って、他の顔のセット (ターゲット) から一致するものを見つけます (画像による顔検索)。 一致するものが見つかると、一致した顔の ID がコンソールに出力されます。

比較の対象となる顔を検出する

まず、2 つ目の顔検出メソッドを定義します。 顔を比較するためにはまず、画像で顔を検出する必要があります。また、この検出メソッドは比較操作向けに最適化されています。 前のセクションほど詳細には顔の属性を抽出せず、また、別の認識モデルを使用しています。

async function DetectFaceRecognize(url) {
    // Detect faces from image URL. Since only recognizing, use the recognition model 4.
    // We use detection model 3 because we are not retrieving attributes.
    let detected_faces = await client.face.detectWithUrl(url,
        {
            detectionModel: "detection_03",
            recognitionModel: "recognition_04"
        });
    return detected_faces;
}

一致するものを探す

次のメソッドでは、一連のターゲット画像と単一のソース画像から顔を検出します。 その後、それらを比較し、ソース画像と似ているターゲット画像をすべて見つけます。 最後に、一致の詳細がコンソールに出力されます。

async function FindSimilar() {
    console.log("========FIND SIMILAR========");
    console.log();

    const source_image_file_name = "findsimilar.jpg";
    const target_image_file_names = [
        "Family1-Dad1.jpg",
        "Family1-Daughter1.jpg",
        "Family1-Mom1.jpg",
        "Family1-Son1.jpg",
        "Family2-Lady1.jpg",
        "Family2-Man1.jpg",
        "Family3-Lady1.jpg",
        "Family3-Man1.jpg"
    ];

    let target_face_ids = (await Promise.all (target_image_file_names.map (async function (target_image_file_name) {
        // Detect faces from target image url.
        var faces = await DetectFaceRecognize(image_base_url + target_image_file_name);
        console.log(faces.length + " face(s) detected from image: " +  target_image_file_name + ".");
        return faces.map (function (face) { return face.faceId });;
    }))).flat();

    // Detect faces from source image url.
    let detected_faces = await DetectFaceRecognize(image_base_url + source_image_file_name);

    // Find a similar face(s) in the list of IDs. Comapring only the first in list for testing purposes.
    let results = await client.face.findSimilar(detected_faces[0].faceId, { faceIds : target_face_ids });
    results.forEach (function (result) {
        console.log("Faces from: " + source_image_file_name + " and ID: " + result.faceId + " are similar with confidence: " + result.confidence + ".");
    });
    console.log();
}

顔を識別する

識別操作では、1 人の人物 (または複数人) の画像を受け取り、その画像内でそれぞれの顔の同一性を見つけます (顔認識検索)。 検出された顔はそれぞれ、顔の特徴が確認されているさまざまな Person オブジェクトのデータベース、つまり PersonGroup と比較されます。 識別操作を行うには、最初に PersonGroup を作成してトレーニングする必要があります。

顔を PersonGroup に追加する

次の関数を作成して、PersonGroup に顔を追加します。

async function AddFacesToPersonGroup(person_dictionary, person_group_id) {
    console.log ("Adding faces to person group...");
    // The similar faces will be grouped into a single person group person.
    
    await Promise.all (Object.keys(person_dictionary).map (async function (key) {
        const value = person_dictionary[key];

        // Wait briefly so we do not exceed rate limits.
        await sleep (1000);

        let person = await client.personGroupPerson.create(person_group_id, { name : key });
        console.log("Create a person group person: " + key + ".");

        // Add faces to the person group person.
        await Promise.all (value.map (async function (similar_image) {
            console.log("Add face to the person group person: (" + key + ") from image: " + similar_image + ".");
            await client.personGroupPerson.addFaceFromUrl(person_group_id, person.personId, image_base_url + similar_image);
        }));
    }));

    console.log ("Done adding faces to person group.");
}

PersonGroup のトレーニングを待機する

次のヘルパー関数を作成して、PersonGroup のトレーニングの終了を待ちます。

async function WaitForPersonGroupTraining(person_group_id) {
    // Wait so we do not exceed rate limits.
    console.log ("Waiting 10 seconds...");
    await sleep (10000);
    let result = await client.personGroup.getTrainingStatus(person_group_id);
    console.log("Training status: " + result.status + ".");
    if (result.status !== "succeeded") {
        await WaitForPersonGroupTraining(person_group_id);
    }
}

PersonGroup を作成する

コード例を次に示します。

  • PersonGroup を作成します
  • 以前に定義した AddFacesToPersonGroup を呼び出して、PersonGroup に顔を追加します。
  • PersonGroup をトレーニングします。
  • PersonGroup 内の顔を識別します。

これで、この PersonGroup とそれに関連付けられた Person オブジェクトを検証、識別、グループ化の各操作で使用する準備が整いました。

async function IdentifyInPersonGroup() {
    console.log("========IDENTIFY FACES========");
    console.log();

// Create a dictionary for all your images, grouping similar ones under the same key.
    const person_dictionary = {
        "Family1-Dad" : ["Family1-Dad1.jpg", "Family1-Dad2.jpg"],
        "Family1-Mom" : ["Family1-Mom1.jpg", "Family1-Mom2.jpg"],
        "Family1-Son" : ["Family1-Son1.jpg", "Family1-Son2.jpg"],
        "Family1-Daughter" : ["Family1-Daughter1.jpg", "Family1-Daughter2.jpg"],
        "Family2-Lady" : ["Family2-Lady1.jpg", "Family2-Lady2.jpg"],
        "Family2-Man" : ["Family2-Man1.jpg", "Family2-Man2.jpg"]
    };

    // A group photo that includes some of the persons you seek to identify from your dictionary.
    let source_image_file_name = "identification1.jpg";

    // Create a person group. 
    console.log("Creating a person group with ID: " + person_group_id);
    await client.personGroup.create(person_group_id, { name : person_group_id, recognitionModel : "recognition_04" });

    await AddFacesToPersonGroup(person_dictionary, person_group_id);

    // Start to train the person group.
    console.log();
    console.log("Training person group: " + person_group_id + ".");
    await client.personGroup.train(person_group_id);

    await WaitForPersonGroupTraining(person_group_id);
    console.log();

    // Detect faces from source image url.
    let face_ids = (await DetectFaceRecognize(image_base_url + source_image_file_name)).map (face => face.faceId);

// Identify the faces in a person group.
    let results = await client.face.identify(face_ids, { personGroupId : person_group_id});
    await Promise.all (results.map (async function (result) {
        let person = await client.personGroupPerson.get(person_group_id, result.candidates[0].personId);
        console.log("Person: " + person.name + " is identified for face in: " + source_image_file_name + " with ID: " + result.faceId + ". Confidence: " + result.candidates[0].confidence + ".");
    }));
    console.log();
}

ヒント

ローカル画像から PersonGroup を作成することもできます。 AddFaceFromStream などの PersonGroupPerson メソッドを参照してください。

メイン

最後に、main 関数を作成し、呼び出します。

async function main() {
    await DetectFaceExtract();
    await FindSimilar();
    await IdentifyInPersonGroup();
    console.log ("Done.");
}
main();

アプリケーションの実行

クイック スタート ファイルで node コマンドを使用して、アプリケーションを実行します。

node index.js

リソースをクリーンアップする

Cognitive Services サブスクリプションをクリーンアップして削除したい場合は、リソースまたはリソース グループを削除することができます。 リソース グループを削除すると、それに関連付けられている他のリソースも削除されます。

次のステップ

このクイックスタートでは、JavaScript 用の Face クライアント ライブラリを使用して基本的な顔認識タスクを行う方法について学習しました。 次に、さまざまな顔検出モデルと、ユース ケースに適したモデルを指定する方法について学習します。

Python 用 Face クライアント ライブラリを使用して顔認識を開始します。 以下の手順に従って、パッケージをインストールし、基本タスクのコード例を試してみましょう。 Face サービスは、画像内の人間の顔を検出および認識するための高度なアルゴリズムへのアクセスを提供します。

Python 用 Face クライアント ライブラリを使用すると、次のことができます。

リファレンス ドキュメント | ライブラリのソース コード | パッケージ (PiPy) | サンプル

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します
  • Python 3.x
    • Python のインストールには、pip が含まれている必要があります。 pip がインストールされているかどうかを確認するには、コマンド ラインで pip --version を実行します。 最新バージョンの Python をインストールして pip を入手してください。
  • Azure サブスクリプションを入手したら、Azure portal で Face リソースを作成し、キーとエンドポイントを取得します。 デプロイされたら、 [リソースに移動] をクリックします。
    • 対象のアプリケーションを Face API に接続するには、作成したリソースのキーとエンドポイントが必要です。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。
    • Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。

設定

クライアント ライブラリをインストールする

Python をインストールしたら、次を使用してクライアント ライブラリをインストールすることができます。

pip install --upgrade azure-cognitiveservices-vision-face

新しい Python アプリケーションを作成する

新しい Python スクリプト (たとえば quickstart-file.py) を作成します。 次に、それを任意のエディターまたは IDE で開き、以下のライブラリをインポートします。

import asyncio
import io
import glob
import os
import sys
import time
import uuid
import requests
from urllib.parse import urlparse
from io import BytesIO
# To install this module, run:
# python -m pip install Pillow
from PIL import Image, ImageDraw
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.vision.face.models import TrainingStatusType, Person

ヒント

クイックスタートのコード ファイル全体を一度にご覧いただけます。 これは GitHub にあり、このクイックスタートのコード例が含まれています。

次に、リソースの Azure エンドポイントおよびキー用の変数を作成します。

# This key will serve all examples in this document.
KEY = "PASTE_YOUR_FACE_SUBSCRIPTION_KEY_HERE"

# This endpoint will be used in all examples in this quickstart.
ENDPOINT = "PASTE_YOUR_FACE_ENDPOINT_HERE"

重要

Azure Portal にアクセスします。 「前提条件」セクションで作成した Face リソースが正常にデプロイされた場合、 [次の手順] の下にある [リソースに移動] ボタンをクリックします。 キーとエンドポイントは、リソースの [key and endpoint](キーとエンドポイント) ページの [リソース管理] にあります。

終わったらコードからキーを削除し、公開しないよう注意してください。 運用環境では、資格情報を安全に格納して利用するための方法を用いることを検討してください。 たとえば、Azure Key Vault が考えられます。

オブジェクト モデル

以下のクラスとインターフェイスにより、Face Python クライアント ライブラリの主要な機能の一部が処理されます。

名前 説明
FaceClient このクラスは、Face サービスを使用するための承認を表し、すべての Face 機能に必要です。 サブスクリプション情報を使用してこれをインスタンス化し、他のクラスのインスタンスを生成するために使用します。
FaceOperations このクラスは、人間の顔に対して実行できる基本的な検出と認識のタスクを処理します。
DetectedFace このクラスは、画像内の 1 つの顔から検出されたすべてのデータを表します。 これを使用して、顔に関する詳細情報を取得できます。
FaceListOperations このクラスは、クラウドに格納された FaceList コンストラクトを管理します。これには、さまざまな顔のセットが格納されます。
PersonGroupPersonOperations このクラスは、クラウドに格納された Person コンストラクトを管理します。これには、1 人の人物に属している顔のセットが格納されます。
PersonGroupOperations このクラスは、クラウドに格納された PersonGroup コンストラクトを管理します。これには、さまざまな Person オブジェクトのセットが格納されます。
ShapshotOperations このクラスは、スナップショット機能を管理します。これを使用すると、クラウドベースのすべての顔データを一時的に保存し、そのデータを新しい Azure サブスクリプションに移行することができます。

コード例

これらのコード スニペットでは、Python 用 Face クライアント ライブラリを使用して以下のタスクを実行する方法が示されています。

クライアントを認証する

ご利用のエンドポイントとキーを使用してクライアントをインスタンス化します。 キーを使用して CognitiveServicesCredentials オブジェクトを作成し、それをエンドポイントと共に使用して、FaceClient オブジェクトを作成します。

# Create an authenticated FaceClient.
face_client = FaceClient(ENDPOINT, CognitiveServicesCredentials(KEY))

画像内の顔を検出する

次のコードは、リモート画像内の顔を検出します。 検出された顔の ID をコンソールに出力し、プログラムのメモリにも格納します。 次に、複数の人物が含まれている画像内の顔を検出し、それらの ID もコンソールに出力します。 detect_with_url メソッドのパラメーターを変更することで、DetectedFace オブジェクトごとに異なる情報を返すことができます。

# Detect a face in an image that contains a single face
single_face_image_url = 'https://www.biography.com/.image/t_share/MTQ1MzAyNzYzOTgxNTE0NTEz/john-f-kennedy---mini-biography.jpg'
single_image_name = os.path.basename(single_face_image_url)
# We use detection model 3 to get better performance.
detected_faces = face_client.face.detect_with_url(url=single_face_image_url, detection_model='detection_03')
if not detected_faces:
    raise Exception('No face detected from image {}'.format(single_image_name))

# Display the detected face ID in the first single-face image.
# Face IDs are used for comparison to faces (their IDs) detected in other images.
print('Detected face ID from', single_image_name, ':')
for face in detected_faces: print (face.face_id)
print()

# Save this ID for use in Find Similar
first_image_face_ID = detected_faces[0].face_id

ヒント

また、ローカルの画像から顔を検出することもできます。 FaceOperations のメソッドを参照してください (detect_with_stream など)。

顔を表示してフレームに収める

次のコードは、指定された画像をディスプレイに出力し、DetectedFace.faceRectangle プロパティを使用して顔の周りに四角形を描画します。

# Detect a face in an image that contains a single face
single_face_image_url = 'https://raw.githubusercontent.com/Microsoft/Cognitive-Face-Windows/master/Data/detection1.jpg'
single_image_name = os.path.basename(single_face_image_url)
# We use detection model 3 to get better performance.
detected_faces = face_client.face.detect_with_url(url=single_face_image_url, detection_model='detection_03')
if not detected_faces:
    raise Exception('No face detected from image {}'.format(single_image_name))

# Convert width height to a point in a rectangle
def getRectangle(faceDictionary):
    rect = faceDictionary.face_rectangle
    left = rect.left
    top = rect.top
    right = left + rect.width
    bottom = top + rect.height
    
    return ((left, top), (right, bottom))

def drawFaceRectangles() :
# Download the image from the url
    response = requests.get(single_face_image_url)
    img = Image.open(BytesIO(response.content))

# For each face returned use the face rectangle and draw a red box.
    print('Drawing rectangle around face... see popup for results.')
    draw = ImageDraw.Draw(img)
    for face in detected_faces:
        draw.rectangle(getRectangle(face), outline='red')

# Display the image in the default image browser.
    img.show()

# Uncomment this to show the face rectangles.
#    drawFaceRectangles()

顔の周囲に赤い四角形が描画されている若い女性

似た顔の検索

以下のコードでは、検出された顔 (ソース) を 1 つ受け取って、他の顔のセット (ターゲット) から一致するものを見つけます (画像による顔検索)。 一致するものが見つかると、一致した顔の ID がコンソールに出力されます。

一致するものを探す

最初に、上のセクション (「画像内の顔を検出する」) のコードを実行して、1 つの顔への参照を保存します。 次に、以下のコードを実行して、グループ画像内の複数の顔への参照を取得します。

# Detect the faces in an image that contains multiple faces
# Each detected face gets assigned a new ID
multi_face_image_url = "http://www.historyplace.com/kennedy/president-family-portrait-closeup.jpg"
multi_image_name = os.path.basename(multi_face_image_url)
# We use detection model 3 to get better performance.
detected_faces2 = face_client.face.detect_with_url(url=multi_face_image_url, detection_model='detection_03')

次に、以下のコード ブロックを追加して、グループ内で最初の顔のインスタンスを探します。 この動作を変更する方法を学習するには、find_similar メソッドを参照してください。

# Search through faces detected in group image for the single face from first image.
# First, create a list of the face IDs found in the second image.
second_image_face_IDs = list(map(lambda x: x.face_id, detected_faces2))
# Next, find similar face IDs like the one detected in the first image.
similar_faces = face_client.face.find_similar(face_id=first_image_face_ID, face_ids=second_image_face_IDs)
if not similar_faces:
    print('No similar faces found in', multi_image_name, '.')

次のコードを使用して、一致の詳細をコンソールに出力します。

# Print the details of the similar faces detected
else:
    print('Similar faces found in', multi_image_name + ':')
    for face in similar_faces:
        first_image_face_ID = face.face_id
        # The similar face IDs of the single face image and the group image do not need to match, 
        # they are only used for identification purposes in each image.
        # The similar faces are matched using the Cognitive Services algorithm in find_similar().
        face_info = next(x for x in detected_faces2 if x.face_id == first_image_face_ID)
        if face_info:
            print('  Face ID: ', first_image_face_ID)
            print('  Face rectangle:')
            print('    Left: ', str(face_info.face_rectangle.left))
            print('    Top: ', str(face_info.face_rectangle.top))
            print('    Width: ', str(face_info.face_rectangle.width))
            print('    Height: ', str(face_info.face_rectangle.height))

PersonGroup を作成してトレーニングする

次のコードでは、3 つの異なる Person オブジェクトを持つ PersonGroup を作成します。 各 Person が例の画像のセットに関連付けられ、各人物を認識できるようにトレーニングが行われます。

PersonGroup を作成する

このシナリオの手順を実行するには、プロジェクトのルート ディレクトリに画像 (https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/Face/images ) を保存する必要があります。

この画像のグループには、3 人の異なる人物に対応する顔画像の 3 つのセットが含まれています。 このコードでは、3 つの Person オブジェクトを定義し、それらを womanman、および child で始まる画像ファイルに関連付けます。

画像の設定後、作成する PersonGroup オブジェクトのために、スクリプトの先頭でラベルを定義します。

# Used in the Person Group Operations and Delete Person Group examples.
# You can call list_person_groups to print a list of preexisting PersonGroups.
# SOURCE_PERSON_GROUP_ID should be all lowercase and alphanumeric. For example, 'mygroupname' (dashes are OK).
PERSON_GROUP_ID = str(uuid.uuid4()) # assign a random ID (or name it anything)

# Used for the Delete Person Group example.
TARGET_PERSON_GROUP_ID = str(uuid.uuid4()) # assign a random ID (or name it anything)

次に、以下のコードをスクリプトの末尾に追加します。 このコードでは、PersonGroup オブジェクトと 3 つの Person オブジェクトが作成されます。

'''
Create the PersonGroup
'''
# Create empty Person Group. Person Group ID must be lower case, alphanumeric, and/or with '-', '_'.
print('Person group:', PERSON_GROUP_ID)
face_client.person_group.create(person_group_id=PERSON_GROUP_ID, name=PERSON_GROUP_ID)

# Define woman friend
woman = face_client.person_group_person.create(PERSON_GROUP_ID, "Woman")
# Define man friend
man = face_client.person_group_person.create(PERSON_GROUP_ID, "Man")
# Define child friend
child = face_client.person_group_person.create(PERSON_GROUP_ID, "Child")

顔を人物に割り当てる

次のコードでは、画像をプレフィックスで並べ替え、顔を検出し、顔を各 Person オブジェクトに割り当てます。

'''
Detect faces and register to correct person
'''
# Find all jpeg images of friends in working directory
woman_images = [file for file in glob.glob('*.jpg') if file.startswith("w")]
man_images = [file for file in glob.glob('*.jpg') if file.startswith("m")]
child_images = [file for file in glob.glob('*.jpg') if file.startswith("ch")]

# Add to a woman person
for image in woman_images:
    w = open(image, 'r+b')
    face_client.person_group_person.add_face_from_stream(PERSON_GROUP_ID, woman.person_id, w)

# Add to a man person
for image in man_images:
    m = open(image, 'r+b')
    face_client.person_group_person.add_face_from_stream(PERSON_GROUP_ID, man.person_id, m)

# Add to a child person
for image in child_images:
    ch = open(image, 'r+b')
    face_client.person_group_person.add_face_from_stream(PERSON_GROUP_ID, child.person_id, ch)

ヒント

URL によって参照されたリモート画像から PersonGroup を作成することもできます。 PersonGroupPersonOperations のメソッドを参照してください (add_face_from_url など)。

PersonGroup をトレーニングする

顔を割り当てたら、PersonGroup をトレーニングして、その各 Person オブジェクトに関連付けられている視覚的特徴を識別できるようにする必要があります。 次のコードは、非同期の train メソッドを呼び出し、結果をポーリングして、状態をコンソールに出力します。

'''
Train PersonGroup
'''
print()
print('Training the person group...')
# Train the person group
face_client.person_group.train(PERSON_GROUP_ID)

while (True):
    training_status = face_client.person_group.get_training_status(PERSON_GROUP_ID)
    print("Training status: {}.".format(training_status.status))
    print()
    if (training_status.status is TrainingStatusType.succeeded):
        break
    elif (training_status.status is TrainingStatusType.failed):
        face_client.person_group.delete(person_group_id=PERSON_GROUP_ID)
        sys.exit('Training the person group has failed.')
    time.sleep(5)

ヒント

Face API は、本質的に静的な一連の事前構築済みモデルで実行されます (サービスの実行中にモデルのパフォーマンスが低下したり改善されたりすることはありません)。 Microsoft により、まったく新しいモデル バージョンに移行することなくモデルのバックエンドが更新されると、モデルによって生成される結果が変わる可能性があります。 より新しいバージョンのモデルを利用するには、同じ登録画像でより新しいモデルをパラメーターとして指定し、PersonGroup を再トレーニングすることができます。

顔を識別する

識別操作では、人物 (1人または複数人) の画像を受け取り、その画像に含まれるそれぞれの顔の同一性を見つけます (顔認識検索)。 検出された顔はそれぞれ、顔の特徴が確認されているさまざまな Person オブジェクトのデータベース、つまり PersonGroup と比較されます。

重要

この例を実行するには、まず、「PersonGroup を作成してトレーニングする」のコードを実行する必要があります。

テスト画像を取得する

次のコードは、プロジェクトのルートで画像 test-image-person-group.jpg を探し、画像内の顔を検出します。 この画像は、PersonGroup の管理に使用される画像と同じ場所 (https://github.com/Azure-Samples/cognitive-services-sample-data-files/tree/master/Face/images ) にあります。

'''
Identify a face against a defined PersonGroup
'''
# Group image for testing against
test_image_array = glob.glob('test-image-person-group.jpg')
image = open(test_image_array[0], 'r+b')

print('Pausing for 60 seconds to avoid triggering rate limit on free account...')
time.sleep (60)

# Detect faces
face_ids = []
# We use detection model 3 to get better performance.
faces = face_client.face.detect_with_stream(image, detection_model='detection_03')
for face in faces:
    face_ids.append(face.face_id)

顔を識別する

identify メソッドは、検出された顔の配列を受け取り、それらを PersonGroup と比較します。 検出された顔を Person と照合できる場合は、結果を保存します。 このコードは、詳細な一致結果をコンソールに出力します。

# Identify faces
results = face_client.face.identify(face_ids, PERSON_GROUP_ID)
print('Identifying faces in {}'.format(os.path.basename(image.name)))
if not results:
    print('No person identified in the person group for faces from {}.'.format(os.path.basename(image.name)))
for person in results:
    if len(person.candidates) > 0:
        print('Person for face ID {} is identified in {} with a confidence of {}.'.format(person.face_id, os.path.basename(image.name), person.candidates[0].confidence)) # Get topmost confidence score
    else:
        print('No person identified for face ID {} in {}.'.format(person.face_id, os.path.basename(image.name)))

顔を確認する

確認操作では、顔 ID と、別の顔 ID または Person オブジェクトのいずれかを取得し、同じ人に属しているかどうかを判断します。

次のコードでは、2 つのソース画像から顔を検出し、ターゲット画像から検出された顔と照らしてそれらを確認します。

テスト イメージを取得する

次のコード ブロックでは、確認操作のソース画像とターゲット画像を指す変数を宣言します。

# Base url for the Verify and Facelist/Large Facelist operations
IMAGE_BASE_URL = 'https://csdx.blob.core.windows.net/resources/Face/Images/'
# Create a list to hold the target photos of the same person
target_image_file_names = ['Family1-Dad1.jpg', 'Family1-Dad2.jpg']
# The source photos contain this person
source_image_file_name1 = 'Family1-Dad3.jpg'
source_image_file_name2 = 'Family1-Son1.jpg'

確認対象の顔を検出する

次のコードは、ソース画像とターゲット画像から顔を検出して、それらを変数に保存します。

# Detect face(s) from source image 1, returns a list[DetectedFaces]
# We use detection model 3 to get better performance.
detected_faces1 = face_client.face.detect_with_url(IMAGE_BASE_URL + source_image_file_name1, detection_model='detection_03')
# Add the returned face's face ID
source_image1_id = detected_faces1[0].face_id
print('{} face(s) detected from image {}.'.format(len(detected_faces1), source_image_file_name1))

# Detect face(s) from source image 2, returns a list[DetectedFaces]
detected_faces2 = face_client.face.detect_with_url(IMAGE_BASE_URL + source_image_file_name2, detection_model='detection_03')
# Add the returned face's face ID
source_image2_id = detected_faces2[0].face_id
print('{} face(s) detected from image {}.'.format(len(detected_faces2), source_image_file_name2))

# List for the target face IDs (uuids)
detected_faces_ids = []
# Detect faces from target image url list, returns a list[DetectedFaces]
for image_file_name in target_image_file_names:
    # We use detection model 3 to get better performance.
    detected_faces = face_client.face.detect_with_url(IMAGE_BASE_URL + image_file_name, detection_model='detection_03')
    # Add the returned face's face ID
    detected_faces_ids.append(detected_faces[0].face_id)
    print('{} face(s) detected from image {}.'.format(len(detected_faces), image_file_name))

確認の結果を取得する

次のコードでは、各ソース画像をターゲット画像と比較し、同じ人物のものであるかどうかを示すメッセージを出力します。

# Verification example for faces of the same person. The higher the confidence, the more identical the faces in the images are.
# Since target faces are the same person, in this example, we can use the 1st ID in the detected_faces_ids list to compare.
verify_result_same = face_client.face.verify_face_to_face(source_image1_id, detected_faces_ids[0])
print('Faces from {} & {} are of the same person, with confidence: {}'
    .format(source_image_file_name1, target_image_file_names[0], verify_result_same.confidence)
    if verify_result_same.is_identical
    else 'Faces from {} & {} are of a different person, with confidence: {}'
        .format(source_image_file_name1, target_image_file_names[0], verify_result_same.confidence))

# Verification example for faces of different persons.
# Since target faces are same person, in this example, we can use the 1st ID in the detected_faces_ids list to compare.
verify_result_diff = face_client.face.verify_face_to_face(source_image2_id, detected_faces_ids[0])
print('Faces from {} & {} are of the same person, with confidence: {}'
    .format(source_image_file_name2, target_image_file_names[0], verify_result_diff.confidence)
    if verify_result_diff.is_identical
    else 'Faces from {} & {} are of a different person, with confidence: {}'
        .format(source_image_file_name2, target_image_file_names[0], verify_result_diff.confidence))

アプリケーションの実行

python コマンドを使用して、アプリケーション ディレクトリから顔認識アプリを実行します。

python quickstart-file.py

リソースをクリーンアップする

Cognitive Services サブスクリプションをクリーンアップして削除したい場合は、リソースまたはリソース グループを削除することができます。 リソース グループを削除すると、それに関連付けられている他のリソースも削除されます。

このクイックスタートで作成してある PersonGroup を削除したい場合は、スクリプトで次のコードを実行します。

# Delete the main person group.
face_client.person_group.delete(person_group_id=PERSON_GROUP_ID)
print("Deleted the person group {} from the source location.".format(PERSON_GROUP_ID))
print()

次のステップ

このクイックスタートでは、Python 用の Face クライアント ライブラリを使用して基本的な顔認識タスクを行う方法について学習しました。 次に、さまざまな顔検出モデルと、ユース ケースに適したモデルを指定する方法について学習します。

Face REST API を使用して顔認識を開始します。 Face サービスは、画像内の人間の顔を検出および認識するための高度なアルゴリズムへのアクセスを提供します。

Face REST API を使用して、次のことを行います。

注意

このクイックスタートでは、cURL コマンドを使用して REST API を呼び出します。 また、プログラミング言語を使用して REST API を呼び出すこともできます。 GitHub のサンプルを参照して、C#PythonJavaJavaScriptGo の例をご確認ください。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します
  • Azure サブスクリプションを入手したら、Azure portal で Face リソースを作成し、キーとエンドポイントを取得します。 デプロイされたら、 [リソースに移動] をクリックします。
    • 対象のアプリケーションを Face API に接続するには、作成したリソースのキーとエンドポイントが必要です。 このクイックスタートで後に示すコードに、自分のキーとエンドポイントを貼り付けます。
    • Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。
  • PowerShell バージョン 6.0 以降、または同様のコマンド ライン アプリケーション。

画像内の顔を検出する

Face API を呼び出して、顔の属性データを画像から取得するには、次のようなコマンドを使用します。 まず、テキスト エディターにコードをコピーしてください。実行する前に、コマンドの一部に変更を加える必要があります。

curl -H "Ocp-Apim-Subscription-Key: TODO_INSERT_YOUR_FACE_SUBSCRIPTION_KEY_HERE" "TODO_INSERT_YOUR_FACE_ENDPOINT_HERE/face/v1.0/detect?detectionModel=detection_03&returnFaceId=true&returnFaceLandmarks=false" -H "Content-Type: application/json" --data-ascii "{\"url\":\"https://upload.wikimedia.org/wikipedia/commons/c/c3/RH_Louise_Lillian_Gish.jpg\"}"

次の変更を行います。

  1. Ocp-Apim-Subscription-Key を、有効な Face サブスクリプション キーに割り当てます。
  2. このクエリ URL の最初の部分を、ご自分のサブスクリプション キーに対応するエンドポイントに合わせて変更します。

    注意

    2019 年 7 月 1 日より後に作成された新しいリソースには、カスタム サブドメイン名が使用されます。 リージョンのエンドポイントの詳細および全一覧については、「Cognitive Services のカスタム サブドメイン名」を参照してください。

  3. 必要に応じて、別の画像を指すように要求の本文の URL を変更します。

変更を加えたら、コマンド プロンプトを開いて新しいコマンドを入力します。

結果を確認する

コンソール ウィンドウに、顔の情報が JSON データとして表示されます。 次に例を示します。

[
  {
    "faceId": "49d55c17-e018-4a42-ba7b-8cbbdfae7c6f",
    "faceRectangle": {
      "top": 131,
      "left": 177,
      "width": 162,
      "height": 162
    }
  }
]  

顔の属性の取得

顔の属性を抽出するには、Detect API をもう一度呼び出します。ただし、detectionModeldetection_01 に設定します。 returnFaceAttributes クエリ パラメーターも追加します。 このコマンドは、次のようになります。 先ほどと同様、Face サブスクリプション キーとエンドポイントを挿入します。

curl -H "Ocp-Apim-Subscription-Key: TODO_INSERT_YOUR_FACE_SUBSCRIPTION_KEY_HERE" "TODO_INSERT_YOUR_FACE_ENDPOINT_HERE/face/v1.0/detect?detectionModel=detection_01&returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise" -H "Content-Type: application/json" --data-ascii "{\"url\":\"https://upload.wikimedia.org/wikipedia/commons/c/c3/RH_Louise_Lillian_Gish.jpg\"}"

結果を確認する

これで、返される顔の情報に顔の属性が追加されます。 次に例を示します。

[
  {
    "faceId": "49d55c17-e018-4a42-ba7b-8cbbdfae7c6f",
    "faceRectangle": {
      "top": 131,
      "left": 177,
      "width": 162,
      "height": 162
    },
    "faceAttributes": {
      "smile": 0,
      "headPose": {
        "pitch": 0,
        "roll": 0.1,
        "yaw": -32.9
      },
      "gender": "female",
      "age": 22.9,
      "facialHair": {
        "moustache": 0,
        "beard": 0,
        "sideburns": 0
      },
      "glasses": "NoGlasses",
      "emotion": {
        "anger": 0,
        "contempt": 0,
        "disgust": 0,
        "fear": 0,
        "happiness": 0,
        "neutral": 0.986,
        "sadness": 0.009,
        "surprise": 0.005
      },
      "blur": {
        "blurLevel": "low",
        "value": 0.06
      },
      "exposure": {
        "exposureLevel": "goodExposure",
        "value": 0.67
      },
      "noise": {
        "noiseLevel": "low",
        "value": 0
      },
      "makeup": {
        "eyeMakeup": true,
        "lipMakeup": true
      },
      "accessories": [],
      "occlusion": {
        "foreheadOccluded": false,
        "eyeOccluded": false,
        "mouthOccluded": false
      },
      "hair": {
        "bald": 0,
        "invisible": false,
        "hairColor": [
          {
            "color": "brown",
            "confidence": 1
          },
          {
            "color": "black",
            "confidence": 0.87
          },
          {
            "color": "other",
            "confidence": 0.51
          },
          {
            "color": "blond",
            "confidence": 0.08
          },
          {
            "color": "red",
            "confidence": 0.08
          },
          {
            "color": "gray",
            "confidence": 0.02
          }
        ]
      }
    }
  }
]

似た顔の検索

この操作では、検出された顔 (ソース) を 1 つ受け取って、他の顔のセット (ターゲット) から一致するものを見つけます (画像による顔検索)。 一致するものが見つかると、一致した顔の ID がコンソールに出力されます。

比較の対象となる顔を検出する

最初に画像内の顔を検出してから、それらを比較する必要があります。 「顔を検出する」セクションで行ったように、このコマンドを実行します。 この検出方法は、比較操作のために最適化されています。 前のセクションほど詳細には顔の属性を抽出せず、また、別の検出モデルを使用しています。

curl -H "Ocp-Apim-Subscription-Key: TODO_INSERT_YOUR_FACE_SUBSCRIPTION_KEY_HERE" "TODO_INSERT_YOUR_FACE_ENDPOINT_HERE/face/v1.0/detect?detectionModel=detection_03&returnFaceId=true&returnFaceLandmarks=false" -H "Content-Type: application/json" --data-ascii "{\"url\":\"https://csdx.blob.core.windows.net/resources/Face/Images/Family1-Dad1.jpg\"}"

JSON 応答内の "faceId" 値を検索し、一時的な場所に保存します。 その後、上記のコマンドを他の画像 URL に対してもう一度呼び出し、それらの顔 ID も保存します。 これらの ID は、似た顔の検索先となる顔のターゲット グループとして使用します。

https://csdx.blob.core.windows.net/resources/Face/Images/Family1-Daughter1.jpg
https://csdx.blob.core.windows.net/resources/Face/Images/Family1-Mom1.jpg
https://csdx.blob.core.windows.net/resources/Face/Images/Family1-Son1.jpg
https://csdx.blob.core.windows.net/resources/Face/Images/Family2-Lady1.jpg
https://csdx.blob.core.windows.net/resources/Face/Images/Family2-Man1.jpg
https://csdx.blob.core.windows.net/resources/Face/Images/Family3-Lady1.jpg
https://csdx.blob.core.windows.net/resources/Face/Images/Family3-Man1.jpg

最後に、照合に使用する 1 つのソースの顔を検出し、その ID を保存します。 この ID は他の ID とは別に保管してください。

https://csdx.blob.core.windows.net/resources/Face/Images/findsimilar.jpg

一致するものを探す

テキスト エディターに次のコマンドをコピーします。

curl -v -X POST "https://westus.api.cognitive.microsoft.com/face/v1.0/findsimilars" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription key}" --data-ascii "{body}"

その後、次の変更を行います。

  1. Ocp-Apim-Subscription-Key を、有効な Face サブスクリプション キーに割り当てます。
  2. このクエリ URL の最初の部分を、ご自分のサブスクリプション キーに対応するエンドポイントに合わせて変更します。

body 値には次の JSON コンテンツを使用します。

{
    "faceId": "",
    "faceIds": [],
    "maxNumOfCandidatesReturned": 10,
    "mode": "matchPerson"
}
  1. "faceId" のソースの顔 ID を使用します。
  2. その他の顔 ID を "faceIds" 配列に単語として貼り付けます。

結果を確認する

顔のクエリに一致する顔の ID の一覧を示す JSON 応答を受け取ります。

[
    {
        "persistedFaceId" : "015839fb-fbd9-4f79-ace9-7675fc2f1dd9",
        "confidence" : 0.82
    },
    ...
] 

リソースをクリーンアップする

Cognitive Services サブスクリプションをクリーンアップして削除したい場合は、リソースまたはリソース グループを削除することができます。 リソース グループを削除すると、それに関連付けられている他のリソースも削除されます。

次のステップ

このクイックスタートでは、Face REST API を使用して基本的な顔認識タスクを行う方法について学習しました。 次に、さまざまな顔検出モデルと、ユース ケースに適したモデルを指定する方法について学習します。