将人脸添加到 PersonGroupAdd faces to a PersonGroup

本指南演示了如何将大量人员和人脸添加到 PersonGroup 对象。This guide demonstrates how to add a large number of persons and faces to a PersonGroup object. 此同一策略还适用于 LargePersonGroup、FaceList 和 LargeFaceList 对象。The same strategy also applies to LargePersonGroup, FaceList, and LargeFaceList objects. 此示例是通过 C# 使用 Azure 认知服务人脸 API .NET 客户端库编写的。This sample is written in C# by using the Azure Cognitive Services Face API .NET client library.

步骤 1:初始化Step 1: Initialization

下面的代码声明了多个变量并实现了一个帮助程序函数来调度人脸添加请求:The following code declares several variables and implements a helper function to schedule the face add requests:

  • PersonCount 是人员总数。PersonCount is the total number of persons.
  • CallLimitPerSecond 是与订阅层相关的每秒最大调用次数。CallLimitPerSecond is the maximum calls per second according to the subscription tier.
  • _timeStampQueue 是一个队列,用于记录请求时间戳。_timeStampQueue is a Queue to record the request timestamps.
  • await WaitCallLimitPerSecondAsync() 将等待,直至可以发送下一请求。await WaitCallLimitPerSecondAsync() waits until it's valid to send the next request.
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);
    }
}

步骤 2:授权 API 调用Step 2: Authorize the API call

使用客户端库时,必须将订阅密钥传递给 FaceClient 类的构造函数。When you use a client library, you must pass your subscription key to the constructor of the FaceClient class. 例如:For example:

private readonly IFaceClient faceClient = new FaceClient(
    new ApiKeyServiceClientCredentials("<SubscriptionKey>"),
    new System.Net.Http.DelegatingHandler[] { });

Azure 门户中创建认知服务后,可以获取订阅密钥。The subscription key can be obtained cognitive service is created in Azure Portal.

步骤 3:创建 PersonGroupStep 3: Create the PersonGroup

创建用于保存人员的 PersonGroup,命名为“MyPersonGroup”。A PersonGroup named "MyPersonGroup" is created to save the persons. 为了确保整体验证,请求时间排入 _timeStampQueue 队列。The request time is enqueued to _timeStampQueue to ensure the overall validation.

const string personGroupId = "mypersongroupid";
const string personGroupName = "MyPersonGroup";
_timeStampQueue.Enqueue(DateTime.UtcNow);
await faceClient.LargePersonGroup.CreateAsync(personGroupId, personGroupName);

步骤 4:为 PersonGroup 创建人员Step 4: Create the persons for the PersonGroup

可同时创建所有人员,为避免超出调用限制,还会应用 await WaitCallLimitPerSecondAsync()Persons are created concurrently, and await WaitCallLimitPerSecondAsync() is also applied to avoid exceeding the call limit.

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

    string personName = $"PersonName#{i}";
    persons[i] = await faceClient.PersonGroupPerson.CreateAsync(personGroupId, personName);
});

步骤 5:向人员添加人脸Step 5: Add faces to the persons

添加到不同人员的人脸是并发处理的。Faces added to different persons are processed concurrently. 为单个特定人员添加的人脸是按顺序处理的。Faces added for one specific person are processed sequentially. 同样,为了确保请求频率在限制范围内,还会调用 await WaitCallLimitPerSecondAsync()Again, await WaitCallLimitPerSecondAsync() is invoked to ensure that the request frequency is within the scope of limitation.

Parallel.For(0, PersonCount, async i =>
{
    Guid personId = persons[i].PersonId;
    string personImageDir = @"/path/to/person/i/images";

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

        using (Stream stream = File.OpenRead(imagePath))
        {
            await faceClient.PersonGroupPerson.AddFaceFromStreamAsync(personGroupId, personId, stream);
        }
    }
});

摘要Summary

在本指南中,你已学习了如何创建包含大量人员和人脸的 PersonGroup。In this guide, you learned the process of creating a PersonGroup with a massive number of persons and faces. 几条提醒事项:Several reminders:

  • 此策略也适用于 FaceLists 和 LargePersonGroups。This strategy also applies to FaceLists and LargePersonGroups.
  • 为 LargePersonGroups 中的不同 FaceLists 或人员添加或删除人脸是并发处理的。Adding or deleting faces to different FaceLists or persons in LargePersonGroups are processed concurrently.
  • 为 LargePersonGroup 中的某个特定 FaceList 或人员添加或删除人脸是按顺序处理的。Adding or deleting faces to one specific FaceList or person in a LargePersonGroup are done sequentially.
  • 为简单起见,本指南省略了如何处理潜在的异常。For simplicity, how to handle a potential exception is omitted in this guide. 若要提高可靠性,请应用适当的重试策略。If you want to enhance more robustness, apply the proper retry policy.

其中解释并演示了以下功能:The following features were explained and demonstrated: