다음을 통해 공유


PersonGroup에 얼굴 추가

주의

Face 서비스 액세스는 책임 있는 AI 원칙을 지원하기 위해 자격 및 사용 기준에 따라 제한됩니다. Face 서비스는 Microsoft 관리 고객 및 파트너만 사용할 수 있습니다. 얼굴 인식 접수 양식을 사용하여 액세스를 적용합니다. 자세한 내용은 얼굴 제한 액세스 페이지를 참조하세요.

이 가이드에서는 PersonGroup 개체에 다수의 사람과 얼굴을 추가하는 방법을 보여줍니다. 동일한 전략이 LargePersonGroup, FaceListLargeFaceList 개체에도 적용됩니다. 이 샘플은 C#으로 작성되었습니다.

설정

다음 코드는 여러 변수를 선언하고 도우미 함수를 구현하여 얼굴 추가 요청을 예약합니다.

  • PersonCount는 총 사람 수입니다.
  • CallLimitPerSecond은 구독 계층에 따른 초당 최대 호출 수입니다.
  • _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"을 만듭니다. 전체 유효성을 검사하기 위해 요청 시간이 _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"]);
        }
    }
});

사람에게 얼굴 추가

다른 사람에 추가된 얼굴은 동시에 처리됩니다. 하나의 특정 사람에 대해 추가된 얼굴은 순차적으로 처리됩니다. 요청 빈도가 제한 범위 이내가 되도록 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을 만드는 프로세스를 배웠습니다. 주요 정보:

  • 이 전략은 FaceListLargePersonGroup에도 적용됩니다.
  • 다른 FaceList 또는 LargePersonGroups의 사람에서 얼굴을 추가하거나 삭제하는 작업은 동시에 처리됩니다.
  • LargePersonGroup의 특정 FaceList 또는 사용자에 얼굴을 추가하거나 삭제하는 작업은 순차적으로 수행 됩니다.

다음 단계

다음으로, 향상된 데이터 구조인 PersonDirectory를 사용하여 얼굴 데이터로 더 많은 작업을 수행하는 방법을 알아봅니다.