주의
Face 서비스 액세스는 책임 있는 AI 원칙을 지원하기 위해 자격 및 사용 기준에 따라 제한됩니다. Face 서비스는 Microsoft 관리 고객 및 파트너만 사용할 수 있습니다. 얼굴 인식 접수 양식을 사용하여 액세스를 적용합니다. 자세한 내용은 얼굴 제한 액세스 페이지를 참조하세요.
이 가이드에서는 PersonGroup 개체에 다수의 사람과 얼굴을 추가하는 방법을 보여줍니다. 동일한 전략이 LargePersonGroup, FaceList 및 LargeFaceList 개체에도 적용됩니다. 이 샘플은 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을 만드는 프로세스를 배웠습니다. 주요 정보:
- 이 전략은 FaceList 및 LargePersonGroup에도 적용됩니다.
- 다른 FaceList 또는 LargePersonGroups의 사람에서 얼굴을 추가하거나 삭제하는 작업은 동시에 처리됩니다.
- LargePersonGroup의 특정 FaceList 또는 사용자에 얼굴을 추가하거나 삭제하는 작업은 순차적으로 수행 됩니다.
다음 단계
다음으로, 향상된 데이터 구조인 PersonDirectory를 사용하여 얼굴 데이터로 더 많은 작업을 수행하는 방법을 알아봅니다.