顔を PersonGroup に追加する

注意

Microsoft の責任ある AI の原則をサポートするために、Face サービスの利用は、適格性と使用基準に基づいて制限されています。 Face サービスは、Microsoft が管理する顧客とパートナーのみが利用できます。 顔認識受付フォームを使用して利用申請を行ってください。 詳細については、「Face の制限付きアクセス」ページを参照してください。

このガイドでは、PersonGroup オブジェクトに膨大な数の人と顔を追加する方法を説明します。 LargePersonGroupFaceListLargeFaceList の各オブジェクトにも同じ方法が適用されます。 この例は C# で記述されています。

初期化

次のコードは、いくつかの変数を宣言し、顔の追加要求をスケジュール設定するヘルパー関数を実装します。

  • PersonCount は、人の合計です。
  • CallLimitPerSecond は、サブスクリプション レベルに基づいた 1 秒あたりの最大呼び出し回数です。
  • _timeStampQueue は、要求のタイムスタンプを記録するキューです。
  • await WaitCallLimitPerSecondAsync() は、次の要求の送信が有効になるまで待機します。
const int PersonCount = 10000;
const int CallLimitPerSecond = 10;
static Queue<DateTime> _timeStampQueue = new Queue<DateTime>(CallLimitPerSecond);

static async Task WaitCallLimitPerSecondAsync()
{
    Monitor.Enter(_timeStampQueue);
    try
    {
        if (_timeStampQueue.Count >= CallLimitPerSecond)
        {
            TimeSpan timeInterval = DateTime.UtcNow - _timeStampQueue.Peek();
            if (timeInterval < TimeSpan.FromSeconds(1))
            {
                await Task.Delay(TimeSpan.FromSeconds(1) - timeInterval);
            }
            _timeStampQueue.Dequeue();
        }
        _timeStampQueue.Enqueue(DateTime.UtcNow);
    }
    finally
    {
        Monitor.Exit(_timeStampQueue);
    }
}

PersonGroup を作成する

このコードでは、人を保存するために "MyPersonGroup" という名前の PersonGroup を作成します。 要求時間が _timeStampQueue にエンキューされ、全体的な検証が保証されます。

const string personGroupId = "mypersongroupid";
const string personGroupName = "MyPersonGroup";
_timeStampQueue.Enqueue(DateTime.UtcNow);
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["name"] = personGroupName, ["recognitionModel"] = "recognition_04" }))))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    await httpClient.PutAsync($"{ENDPOINT}/face/v1.0/persongroups/{personGroupId}", content);
}

PersonGroup に対して人を作成する

このコードは、Personsを同時に作成し、呼び出しレート制限を超えないように await WaitCallLimitPerSecondAsync() を使用します。

string?[] persons = new string?[PersonCount];
Parallel.For(0, PersonCount, async i =>
{
    await WaitCallLimitPerSecondAsync();

    string personName = $"PersonName#{i}";
    using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["name"] = personName }))))
    {
        content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        using (var response = await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/persongroups/{personGroupId}/persons", content))
        {
            string contentString = await response.Content.ReadAsStringAsync();
            persons[i] = (string?)(JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString)?["personId"]);
        }
    }
});

顔を人に追加する

さまざまな人に追加された顔は、同時に処理されます。 特定の 1 人について追加された顔は、順次処理されます。 ここでも、await WaitCallLimitPerSecondAsync() を呼び出して、要求の頻度が制限範囲内になるようにします。

Parallel.For(0, PersonCount, async i =>
{
    string personImageDir = @"/path/to/person/i/images";

    foreach (string imagePath in Directory.GetFiles(personImageDir, "*.jpg"))
    {
        await WaitCallLimitPerSecondAsync();

        using (Stream stream = File.OpenRead(imagePath))
        {
            using (var content = new StreamContent(stream))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/persongroups/{personGroupId}/persons/{persons[i]}/persistedfaces?detectionModel=detection_03", content);
            }
        }
    }
});

まとめ

このガイドでは、膨大な数の人と顔を含む PersonGroup を作成するプロセスについて学びました。 次のことを覚えておいてください。

  • この方法は FaceListsLargePersonGroups にも適用されます。
  • LargePersonGroups 内のさまざまな FaceLists または人への顔の追加や削除は、同時に処理されます。
  • LargePersonGroup 内の特定の 1 つの FaceList または人への顔の追加や削除は、順次処理されます。

次のステップ

次に、強化されたデータ構造である PersonDirectory を使用して、顔データをさらに処理する方法について説明します。