빠른 시작: Face 서비스 사용

Important

Microsoft 제품 또는 서비스를 사용하여 생체 인식 데이터를 처리하는 경우 (i) 보존 기간 및 소멸을 포함하여 데이터 주체에 통지 (ii) 데이터 주체로부터 동의 얻기 및 (iii) 적용 가능한 데이터 보호 요구 사항에 따라 적절하고 필요한 모든 생체 인식 데이터 삭제와 같은 책임이 있습니다. "생체 인식 데이터"는 GDPR 제4조에 명시된 의미를 가지며, 해당하는 경우 다른 데이터 보호 요구 사항에서 동등한 조건을 갖습니다. 관련 정보는 Face의 데이터 및 개인 정보를 참조하세요.

주의

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

.NET용 Face 클라이언트 라이브러리를 사용하여 얼굴 인식을 시작합니다. Azure AI Face 서비스는 이미지에서 사람의 얼굴을 감지하고 인식하기 위한 고급 알고리즘에 대한 액세스를 제공합니다. 다음 단계에 따라 패키지를 설치하고 원격 이미지를 사용하여 기본 얼굴 식별을 위한 예제 코드를 사용해봅니다.

참조 설명서 | 라이브러리 소스 코드 | 패키지(NuGet) | 샘플

필수 조건

  • Azure 구독 - 체험 구독 만들기
  • Visual Studio IDE 또는 현재 버전의 .NET Core.
  • Azure 구독을 보유한 후에는 Azure Portal에서 Face 리소스를 만들어 키와 엔드포인트를 가져옵니다. 배포 후 리소스로 이동을 선택합니다.
    • 애플리케이션을 Face API에 연결하려면 생성한 리소스의 키와 엔드포인트가 필요합니다.
    • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

환경 변수 만들기

이 예제에서는 애플리케이션을 실행하는 로컬 컴퓨터의 환경 변수에 자격 증명을 작성합니다.

Azure Portal로 이동합니다. 필수 구성 요소 섹션에서 만든 리소스가 성공적으로 배포된 경우 다음 단계 아래에서 리소스로 이동을 선택합니다. 리소스 관리 아래에 있는 리소스의 키 및 엔드포인트 페이지에서 키 및 엔드포인트를 찾을 수 있습니다. 리소스 키는 Azure 구독 ID와 동일하지 않습니다.

키 및 엔드포인트에 대한 환경 변수를 설정하려면 콘솔 창을 열고 운영 체제 및 개발 환경에 대한 지침을 따릅니다.

  • FACE_APIKEY 환경 변수를 설정하려면 <your_key>를 리소스에 대한 키 중 하나로 바꿉니다.
  • FACE_ENDPOINT 환경 변수를 설정하려면 <your_endpoint>를 리소스에 대한 엔드포인트로 바꿉니다.

Important

API 키를 사용하는 경우 Azure Key Vault와 같은 다른 위치에 안전하게 저장합니다. API 키를 코드에 직접 포함하지 말고, 공개적으로 게시하지 마세요.

AI 서비스 보안에 대한 자세한 내용은 Azure AI 서비스에 대한 요청 인증을 참조하세요.

setx FACE_APIKEY <your_key>
setx FACE_ENDPOINT <your_endpoint>

환경 변수가 추가되면 콘솔 창을 포함하여 환경 변수를 읽는 실행 중인 프로그램을 다시 시작해야 할 수 있습니다.

얼굴 식별 및 확인

  1. 새 C# 애플리케이션 만들기

    Visual Studio를 사용하여 새 .NET Core 애플리케이션을 만듭니다.

    클라이언트 라이브러리 설치

    새 프로젝트가 만들어지면 솔루션 탐색기에서 마우스 오른쪽 단추로 프로젝트 솔루션을 클릭하고, NuGet 패키지 관리를 선택하여 클라이언트 라이브러리를 설치합니다. 열리는 패키지 관리자에서 찾아보기를 선택하고, 시험판 포함을 선택하고, Azure.AI.Vision.Face를 검색합니다. 최신 버전을 선택한 후 설치를 선택합니다.

  2. 다음 코드를 Program.cs 파일에 추가합니다.

    참고 항목

    접수 양식을 사용하여 Face 서비스에 대한 액세스 권한을 받지 못한 경우 이러한 기능 중 일부는 작동하지 않습니다.

    using System.Net.Http.Headers;
    using System.Text;
    
    using Azure;
    using Azure.AI.Vision.Face;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    namespace FaceQuickstart
    {
        class Program
        {
            static readonly string largePersonGroupId = Guid.NewGuid().ToString();
    
            // URL path for the images.
            const string IMAGE_BASE_URL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/";
    
            // From your Face subscription in the Azure portal, get your subscription key and endpoint.
            static readonly string SUBSCRIPTION_KEY = Environment.GetEnvironmentVariable("FACE_APIKEY") ?? "<apikey>";
            static readonly string ENDPOINT = Environment.GetEnvironmentVariable("FACE_ENDPOINT") ?? "<endpoint>";
    
            static void Main(string[] args)
            {
                // 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.
                FaceRecognitionModel RECOGNITION_MODEL4 = FaceRecognitionModel.Recognition04;
    
                // Authenticate.
                FaceClient client = Authenticate(ENDPOINT, SUBSCRIPTION_KEY);
    
                // Identify - recognize a face(s) in a large person group (a large person group is created in this example).
                IdentifyInLargePersonGroup(client, IMAGE_BASE_URL, RECOGNITION_MODEL4).Wait();
    
                Console.WriteLine("End of quickstart.");
            }
    
            /*
             *	AUTHENTICATE
             *	Uses subscription key and region to create a client.
             */
            public static FaceClient Authenticate(string endpoint, string key)
            {
                return new FaceClient(new Uri(endpoint), new AzureKeyCredential(key));
            }
    
            // Detect faces from image url for recognition purposes. This is a helper method for other functions in this quickstart.
            // Parameter `returnFaceId` of `DetectAsync` must be set to `true` (by default) for recognition purposes.
            // Parameter `returnFaceAttributes` is set to include the QualityForRecognition attribute. 
            // Recognition model must be set to recognition_03 or recognition_04 as a result.
            // Result faces with insufficient quality for recognition are filtered out. 
            // The field `faceId` in returned `DetectedFace`s will be used in Verify and Identify.
            // It will expire 24 hours after the detection call.
            private static async Task<List<FaceDetectionResult>> DetectFaceRecognize(FaceClient faceClient, string url, FaceRecognitionModel recognition_model)
            {
                // Detect faces from image URL.
                Response<IReadOnlyList<FaceDetectionResult>> response = await faceClient.DetectAsync(new Uri(url), FaceDetectionModel.Detection03, recognition_model, returnFaceId: true, [FaceAttributeType.QualityForRecognition]);
                IReadOnlyList<FaceDetectionResult> detectedFaces = response.Value;
                List<FaceDetectionResult> sufficientQualityFaces = new List<FaceDetectionResult>();
                foreach (FaceDetectionResult detectedFace in detectedFaces)
                {
                    var faceQualityForRecognition = detectedFace.FaceAttributes.QualityForRecognition;
                    if (faceQualityForRecognition.HasValue && (faceQualityForRecognition.Value != QualityForRecognition.Low))
                    {
                        sufficientQualityFaces.Add(detectedFace);
                    }
                }
                Console.WriteLine($"{detectedFaces.Count} face(s) with {sufficientQualityFaces.Count} having sufficient quality for recognition detected from image `{Path.GetFileName(url)}`");
    
                return sufficientQualityFaces;
            }
    
            /*
             * IDENTIFY FACES
             * To identify faces, you need to create and define a large person group.
             * The Identify operation takes one or several face IDs from DetectedFace or PersistedFace and a LargePersonGroup and returns 
             * a list of Person objects that each face might belong to. Returned Person objects are wrapped as Candidate objects, 
             * which have a prediction confidence value.
             */
            public static async Task IdentifyInLargePersonGroup(FaceClient client, string url, FaceRecognitionModel 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" } }
                        };
                // A group photo that includes some of the persons you seek to identify from your dictionary.
                string sourceImageFileName = "identification1.jpg";
    
                // Create a large person group.
                Console.WriteLine($"Create a person group ({largePersonGroupId}).");
                HttpClient httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", SUBSCRIPTION_KEY);
                using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["name"] = largePersonGroupId, ["recognitionModel"] = recognitionModel.ToString() }))))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                    await httpClient.PutAsync($"{ENDPOINT}/face/v1.0/largepersongroups/{largePersonGroupId}", content);
                }
                // The similar faces will be grouped into a single large person group person.
                foreach (var groupedFace in personDictionary.Keys)
                {
                    // Limit TPS
                    await Task.Delay(250);
                    string? personId = null;
                    using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["name"] = groupedFace }))))
                    {
                        content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                        using (var response = await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/largepersongroups/{largePersonGroupId}/persons", content))
                        {
                            string contentString = await response.Content.ReadAsStringAsync();
                            personId = (string?)(JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString)?["personId"]);
                        }
                    }
                    Console.WriteLine($"Create a person group person '{groupedFace}'.");
    
                    // Add face to the large person group person.
                    foreach (var similarImage in personDictionary[groupedFace])
                    {
                        Console.WriteLine($"Check whether image is of sufficient quality for recognition");
                        Response<IReadOnlyList<FaceDetectionResult>> response = await client.DetectAsync(new Uri($"{url}{similarImage}"), FaceDetectionModel.Detection03, recognitionModel, returnFaceId: false, [FaceAttributeType.QualityForRecognition]);
                        IReadOnlyList<FaceDetectionResult> detectedFaces1 = response.Value;
                        bool sufficientQuality = true;
                        foreach (var face1 in detectedFaces1)
                        {
                            var faceQualityForRecognition = face1.FaceAttributes.QualityForRecognition;
                            //  Only "high" quality images are recommended for person enrollment
                            if (faceQualityForRecognition.HasValue && (faceQualityForRecognition.Value != QualityForRecognition.High))
                            {
                                sufficientQuality = false;
                                break;
                            }
                        }
    
                        if (!sufficientQuality)
                        {
                            continue;
                        }
    
                        if (detectedFaces1.Count != 1)
                        {
                            continue;
                        }
    
                        // add face to the large person group
                        Console.WriteLine($"Add face to the person group person({groupedFace}) from image `{similarImage}`");
                        using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["url"] = $"{url}{similarImage}" }))))
                        {
                            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                            await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/largepersongroups/{largePersonGroupId}/persons/{personId}/persistedfaces?detectionModel=detection_03", content);
                        }
                    }
                }
    
                // Start to train the large person group.
                Console.WriteLine();
                Console.WriteLine($"Train person group {largePersonGroupId}.");
                await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/largepersongroups/{largePersonGroupId}/train", null);
    
                // Wait until the training is completed.
                while (true)
                {
                    await Task.Delay(1000);
                    string? trainingStatus = null;
                    using (var response = await httpClient.GetAsync($"{ENDPOINT}/face/v1.0/largepersongroups/{largePersonGroupId}/training"))
                    {
                        string contentString = await response.Content.ReadAsStringAsync();
                        trainingStatus = (string?)(JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString)?["status"]);
                    }
                    Console.WriteLine($"Training status: {trainingStatus}.");
                    if ("succeeded".Equals(trainingStatus)) { break; }
                }
                Console.WriteLine();
    
                Console.WriteLine("Pausing for 60 seconds to avoid triggering rate limit on free account...");
                await Task.Delay(60000);
    
                List<Guid> sourceFaceIds = new List<Guid>();
                // Detect faces from source image url.
                List<FaceDetectionResult> detectedFaces = await DetectFaceRecognize(client, $"{url}{sourceImageFileName}", recognitionModel);
    
                // Add detected faceId to sourceFaceIds.
                foreach (var detectedFace in detectedFaces) { sourceFaceIds.Add(detectedFace.FaceId.Value); }
    
                // Identify the faces in a large person group.
                List<Dictionary<string, object>> identifyResults = new List<Dictionary<string, object>>();
                using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["faceIds"] = sourceFaceIds, ["largePersonGroupId"] = largePersonGroupId }))))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                    using (var response = await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/identify", content))
                    {
                        string contentString = await response.Content.ReadAsStringAsync();
                        identifyResults = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(contentString) ?? [];
                    }
                }
    
                foreach (var identifyResult in identifyResults)
                {
                    string faceId = (string)identifyResult["faceId"];
                    List<Dictionary<string, object>> candidates = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(((JArray)identifyResult["candidates"]).ToString()) ?? [];
                    if (candidates.Count == 0)
                    {
                        Console.WriteLine($"No person is identified for the face in: {sourceImageFileName} - {faceId},");
                        continue;
                    }
    
                    string? personName = null;
                    using (var response = await httpClient.GetAsync($"{ENDPOINT}/face/v1.0/largepersongroups/{largePersonGroupId}/persons/{candidates.First()["personId"]}"))
                    {
                        string contentString = await response.Content.ReadAsStringAsync();
                        personName = (string?)(JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString)?["name"]);
                    }
                    Console.WriteLine($"Person '{personName}' is identified for the face in: {sourceImageFileName} - {faceId}," +
                        $" confidence: {candidates.First()["confidence"]}.");
    
                    Dictionary<string, object> verifyResult = new Dictionary<string, object>();
                    using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Dictionary<string, object> { ["faceId"] = faceId, ["personId"] = candidates.First()["personId"], ["largePersonGroupId"] = largePersonGroupId }))))
                    {
                        content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                        using (var response = await httpClient.PostAsync($"{ENDPOINT}/face/v1.0/verify", content))
                        {
                            string contentString = await response.Content.ReadAsStringAsync();
                            verifyResult = JsonConvert.DeserializeObject<Dictionary<string, object>>(contentString) ?? [];
                        }
                    }
                    Console.WriteLine($"Verification result: is a match? {verifyResult["isIdentical"]}. confidence: {verifyResult["confidence"]}");
                }
                Console.WriteLine();
    
                // Delete large person group.
                Console.WriteLine("========DELETE PERSON GROUP========");
                Console.WriteLine();
                await httpClient.DeleteAsync($"{ENDPOINT}/face/v1.0/largepersongroups/{largePersonGroupId}");
                Console.WriteLine($"Deleted the person group {largePersonGroupId}.");
                Console.WriteLine();
            }
        }
    }
    
  3. 애플리케이션 실행

    IDE 창의 위쪽에서 디버그 단추를 클릭하여 애플리케이션을 실행합니다.

출력

========IDENTIFY FACES========

Create a person group (18d1c443-a01b-46a4-9191-121f74a831cd).
Create a person group person 'Family1-Dad'.
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Dad) from image `Family1-Dad1.jpg`
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Dad) from image `Family1-Dad2.jpg`
Create a person group person 'Family1-Mom'.
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Mom) from image `Family1-Mom1.jpg`
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Mom) from image `Family1-Mom2.jpg`
Create a person group person 'Family1-Son'.
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Son) from image `Family1-Son1.jpg`
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Son) from image `Family1-Son2.jpg`

Train person group 18d1c443-a01b-46a4-9191-121f74a831cd.
Training status: succeeded.

Pausing for 60 seconds to avoid triggering rate limit on free account...
4 face(s) with 4 having sufficient quality for recognition detected from image `identification1.jpg`
Person 'Family1-Dad' is identified for the face in: identification1.jpg - ad813534-9141-47b4-bfba-24919223966f, confidence: 0.96807.
Verification result: is a match? True. confidence: 0.96807
Person 'Family1-Mom' is identified for the face in: identification1.jpg - 1a39420e-f517-4cee-a898-5d968dac1a7e, confidence: 0.96902.
Verification result: is a match? True. confidence: 0.96902
No person is identified for the face in: identification1.jpg - 889394b1-e30f-4147-9be1-302beb5573f3,
Person 'Family1-Son' is identified for the face in: identification1.jpg - 0557d87b-356c-48a8-988f-ce0ad2239aa5, confidence: 0.9281.
Verification result: is a match? True. confidence: 0.9281

========DELETE PERSON GROUP========

Deleted the person group 18d1c443-a01b-46a4-9191-121f74a831cd.

End of quickstart.

Face API는 기본적으로 정적인 사전 빌드된 모델 세트에서 실행됩니다(서비스가 실행될 때 모델의 성능이 저하되거나 향상되지 않음). Microsoft에서 완전히 새로운 모델 버전으로 마이그레이션하지 않고 모델의 백엔드를 업데이트하면 모델이 생성하는 결과가 변경될 수 있습니다. 최신 버전의 모델을 사용하려면 PersonGroup을 동일한 등록 이미지를 가진 매개 변수로 지정하여 다시 학습할 수 있습니다.

리소스 정리

Azure AI 서비스 구독을 정리하고 제거하려면 리소스 또는 리소스 그룹을 삭제할 수 있습니다. 리소스 그룹을 삭제하면 해당 리소스 그룹에 연결된 다른 모든 리소스가 함께 삭제됩니다.

다음 단계

이 빠른 시작에서는 .NET용 Face 클라이언트 라이브러리를 사용하여 기본 얼굴 식별을 수행하는 방법을 알아보았습니다. 다음으로, 다양한 얼굴 감지 모델과 사용 사례에 적합한 모델을 지정하는 방법을 알아봅니다.

Python용 Face 클라이언트 라이브러리를 사용하여 얼굴 인식을 시작합니다. 이러한 단계에 따라 패키지를 설치하고 기본 작업을 위한 예제 코드를 사용해 봅니다. Face 서비스는 이미지에서 사람의 얼굴을 감지하고 인식하기 위한 고급 알고리즘에 대한 액세스를 제공합니다. 다음 단계에 따라 패키지를 설치하고 원격 이미지를 사용하여 기본 얼굴 식별을 위한 예제 코드를 사용해봅니다.

참조 설명서 | 라이브러리 소스 코드 | 패키지(PiPy) | 샘플

필수 조건

  • Azure 구독 - 체험 구독 만들기
  • Python 3.x
    • Python 설치에 pip가 포함되어야 합니다. 명령줄에서 pip --version을 실행하여 pip가 설치되어 있는지 확인할 수 있습니다. 최신 버전의 Python을 설치하여 pip를 받으세요.
  • Azure 구독을 보유한 후에는 Azure Portal에서 Face 리소스를 만들어 키와 엔드포인트를 가져옵니다. 배포 후 리소스로 이동을 선택합니다.
    • 애플리케이션을 Face API에 연결하려면 생성한 리소스의 키와 엔드포인트가 필요합니다.
    • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

환경 변수 만들기

이 예제에서는 애플리케이션을 실행하는 로컬 컴퓨터의 환경 변수에 자격 증명을 작성합니다.

Azure Portal로 이동합니다. 필수 구성 요소 섹션에서 만든 리소스가 성공적으로 배포된 경우 다음 단계 아래에서 리소스로 이동을 선택합니다. 리소스 관리 아래에 있는 리소스의 키 및 엔드포인트 페이지에서 키 및 엔드포인트를 찾을 수 있습니다. 리소스 키는 Azure 구독 ID와 동일하지 않습니다.

키 및 엔드포인트에 대한 환경 변수를 설정하려면 콘솔 창을 열고 운영 체제 및 개발 환경에 대한 지침을 따릅니다.

  • FACE_APIKEY 환경 변수를 설정하려면 <your_key>를 리소스에 대한 키 중 하나로 바꿉니다.
  • FACE_ENDPOINT 환경 변수를 설정하려면 <your_endpoint>를 리소스에 대한 엔드포인트로 바꿉니다.

Important

API 키를 사용하는 경우 Azure Key Vault와 같은 다른 위치에 안전하게 저장합니다. API 키를 코드에 직접 포함하지 말고, 공개적으로 게시하지 마세요.

AI 서비스 보안에 대한 자세한 내용은 Azure AI 서비스에 대한 요청 인증을 참조하세요.

setx FACE_APIKEY <your_key>
setx FACE_ENDPOINT <your_endpoint>

환경 변수가 추가되면 콘솔 창을 포함하여 환경 변수를 읽는 실행 중인 프로그램을 다시 시작해야 할 수 있습니다.

얼굴 식별 및 확인

  1. 클라이언트 라이브러리 설치

    Python을 설치한 후, 다음을 사용하여 클라이언트 라이브러리를 설치할 수 있습니다.

    pip install --upgrade azure-ai-vision-face
    
  2. 새 Python 애플리케이션 만들기

    예를 들어 새 Python 스크립트quickstart-file.py를 만듭니다. 그런 다음, 원하는 편집기 또는 IDE에서 이 파일을 열고 다음 코드를 붙여넣습니다.

    참고 항목

    접수 양식을 사용하여 Face 서비스에 대한 액세스 권한을 받지 못한 경우 이러한 기능 중 일부는 작동하지 않습니다.

    import os
    import time
    import uuid
    import requests
    
    from azure.core.credentials import AzureKeyCredential
    from azure.ai.vision.face import FaceClient
    from azure.ai.vision.face.models import (
        FaceAttributeTypeRecognition04,
        FaceDetectionModel,
        FaceRecognitionModel,
        QualityForRecognition,
    )
    
    
    # This key will serve all examples in this document.
    KEY = os.environ["FACE_APIKEY"]
    
    # This endpoint will be used in all examples in this quickstart.
    ENDPOINT = os.environ["FACE_ENDPOINT"]
    
    # Used in the Large Person Group Operations and Delete Large Person Group examples.
    # LARGE_PERSON_GROUP_ID should be all lowercase and alphanumeric. For example, 'mygroupname' (dashes are OK).
    LARGE_PERSON_GROUP_ID = str(uuid.uuid4())  # assign a random ID (or name it anything)
    
    HEADERS = {"Ocp-Apim-Subscription-Key": KEY, "Content-Type": "application/json"}
    
    # Create an authenticated FaceClient.
    with FaceClient(endpoint=ENDPOINT, credential=AzureKeyCredential(KEY)) as face_client:
        '''
        Create the LargePersonGroup
        '''
        # Create empty Large Person Group. Large Person Group ID must be lower case, alphanumeric, and/or with '-', '_'.
        print("Person group:", LARGE_PERSON_GROUP_ID)
        response = requests.put(
            ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}",
            headers=HEADERS,
            json={"name": LARGE_PERSON_GROUP_ID, "recognitionModel": "recognition_04"})
        response.raise_for_status()
    
        # Define woman friend
        response = requests.post(ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/persons", headers=HEADERS, json={"name": "Woman"})
        response.raise_for_status()
        woman = response.json()
        # Define man friend
        response = requests.post(ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/persons", headers=HEADERS, json={"name": "Man"})
        response.raise_for_status()
        man = response.json()
        # Define child friend
        response = requests.post(ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/persons", headers=HEADERS, json={"name": "Child"})
        response.raise_for_status()
        child = response.json()
    
        '''
        Detect faces and register them to each person
        '''
        # Find all jpeg images of friends in working directory (TBD pull from web instead)
        woman_images = [
            "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/Family1-Mom1.jpg",  # noqa: E501
            "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/Family1-Mom2.jpg",  # noqa: E501
        ]
        man_images = [
            "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/Family1-Dad1.jpg",  # noqa: E501
            "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/Family1-Dad2.jpg",  # noqa: E501
        ]
        child_images = [
            "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/Family1-Son1.jpg",  # noqa: E501
            "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/Family1-Son2.jpg",  # noqa: E501
        ]
    
        # Add to woman person
        for image in woman_images:
            # Check if the image is of sufficent quality for recognition.
            sufficientQuality = True
            detected_faces = face_client.detect_from_url(
                url=image,
                detection_model=FaceDetectionModel.DETECTION_03,
                recognition_model=FaceRecognitionModel.RECOGNITION_04,
                return_face_id=True,
                return_face_attributes=[FaceAttributeTypeRecognition04.QUALITY_FOR_RECOGNITION])
            for face in detected_faces:
                if face.face_attributes.quality_for_recognition != QualityForRecognition.HIGH:
                    sufficientQuality = False
                    break
    
            if not sufficientQuality:
                continue
    
            if len(detected_faces) != 1:
                continue
    
            response = requests.post(
                ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/persons/{woman['personId']}/persistedFaces",
                headers=HEADERS,
                json={"url": image})
            response.raise_for_status()
            print(f"face {face.face_id} added to person {woman['personId']}")
    
    
        # Add to man person
        for image in man_images:
            # Check if the image is of sufficent quality for recognition.
            sufficientQuality = True
            detected_faces = face_client.detect_from_url(
                url=image,
                detection_model=FaceDetectionModel.DETECTION_03,
                recognition_model=FaceRecognitionModel.RECOGNITION_04,
                return_face_id=True,
                return_face_attributes=[FaceAttributeTypeRecognition04.QUALITY_FOR_RECOGNITION])
            for face in detected_faces:
                if face.face_attributes.quality_for_recognition != QualityForRecognition.HIGH:
                    sufficientQuality = False
                    break
    
            if not sufficientQuality:
                continue
    
            if len(detected_faces) != 1:
                continue
    
            response = requests.post(
                ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/persons/{man['personId']}/persistedFaces",
                headers=HEADERS,
                json={"url": image})
            response.raise_for_status()
            print(f"face {face.face_id} added to person {man['personId']}")
    
        # Add to child person
        for image in child_images:
            # Check if the image is of sufficent quality for recognition.
            sufficientQuality = True
            detected_faces = face_client.detect_from_url(
                url=image,
                detection_model=FaceDetectionModel.DETECTION_03,
                recognition_model=FaceRecognitionModel.RECOGNITION_04,
                return_face_id=True,
                return_face_attributes=[FaceAttributeTypeRecognition04.QUALITY_FOR_RECOGNITION])
            for face in detected_faces:
                if face.face_attributes.quality_for_recognition != QualityForRecognition.HIGH:
                    sufficientQuality = False
                    break
            if not sufficientQuality:
                continue
    
            if len(detected_faces) != 1:
                continue
    
            response = requests.post(
                ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/persons/{child['personId']}/persistedFaces",
                headers=HEADERS,
                json={"url": image})
            response.raise_for_status()
            print(f"face {face.face_id} added to person {child['personId']}")
    
        '''
        Train LargePersonGroup
        '''
        # Train the large person group
        print(f"Train the person group {LARGE_PERSON_GROUP_ID}")
        response = requests.post(ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/train", headers=HEADERS)
        response.raise_for_status()
    
        while (True):
            response = requests.get(ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}/training", headers=HEADERS)
            response.raise_for_status()
            training_status = response.json()["status"]
            if training_status == "succeeded":
                break
        print(f"The person group {LARGE_PERSON_GROUP_ID} is trained successfully.")
    
        '''
        Identify a face against a defined LargePersonGroup
        '''
        # Group image for testing against
        test_image = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/identification1.jpg"  # noqa: E501
    
        print("Pausing for 60 seconds to avoid triggering rate limit on free account...")
        time.sleep(60)
    
        # Detect faces
        face_ids = []
        # We use detection model 03 to get better performance, recognition model 04 to support quality for
        # recognition attribute.
        faces = face_client.detect_from_url(
            url=test_image,
            detection_model=FaceDetectionModel.DETECTION_03,
            recognition_model=FaceRecognitionModel.RECOGNITION_04,
            return_face_id=True,
            return_face_attributes=[FaceAttributeTypeRecognition04.QUALITY_FOR_RECOGNITION])
        for face in faces:
            # Only take the face if it is of sufficient quality.
            if face.face_attributes.quality_for_recognition != QualityForRecognition.LOW:
                face_ids.append(face.face_id)
    
        # Identify faces
        response = requests.post(
            ENDPOINT + f"/face/v1.0/identify",
            headers=HEADERS,
            json={"faceIds": face_ids, "largePersonGroupId": LARGE_PERSON_GROUP_ID})
        response.raise_for_status()
        results = response.json()
        print("Identifying faces in image")
        if not results:
            print("No person identified in the person group")
        for identifiedFace in results:
            if len(identifiedFace["candidates"]) > 0:
                print(f"Person is identified for face ID {identifiedFace['faceId']} in image, with a confidence of "
                      f"{identifiedFace['candidates'][0]['confidence']}.")  # Get topmost confidence score
    
                # Verify faces
                response = requests.post(
                    ENDPOINT + f"/face/v1.0/verify",
                    headers=HEADERS,
                    json={"faceId": identifiedFace["faceId"], "personId": identifiedFace["candidates"][0]["personId"], "largePersonGroupId": LARGE_PERSON_GROUP_ID})
                response.raise_for_status()
                verify_result = response.json()
                print(f"verification result: {verify_result['isIdentical']}. confidence: {verify_result['confidence']}")
            else:
                print(f"No person identified for face ID {identifiedFace['faceId']} in image.")
    
        print()
    
        # Delete the large person group
        response = requests.delete(ENDPOINT + f"/face/v1.0/largepersongroups/{LARGE_PERSON_GROUP_ID}", headers=HEADERS)
        response.raise_for_status()
        print(f"The person group {LARGE_PERSON_GROUP_ID} is deleted.")
    
        print()
        print("End of quickstart.")
    
    
  3. python 명령을 사용하여 애플리케이션 디렉터리에서 얼굴 인식 앱을 실행합니다.

    python quickstart-file.py
    

    Face API는 기본적으로 정적인 사전 빌드된 모델 세트에서 실행됩니다(서비스가 실행될 때 모델의 성능이 저하되거나 향상되지 않음). Microsoft에서 완전히 새로운 모델 버전으로 마이그레이션하지 않고 모델의 백엔드를 업데이트하면 모델이 생성하는 결과가 변경될 수 있습니다. 최신 버전의 모델을 사용하려면 PersonGroup을 동일한 등록 이미지를 가진 매개 변수로 지정하여 다시 학습할 수 있습니다.

출력

Person group: ad12b2db-d892-48ec-837a-0e7168c18224
face 335a2cb1-5211-4c29-9c45-776dd014b2af added to person 9ee65510-81a5-47e5-9e50-66727f719465
face df57eb50-4a13-4f93-b804-cd108327ad5a added to person 9ee65510-81a5-47e5-9e50-66727f719465
face d8b7b8b8-3ca6-4309-b76e-eeed84f7738a added to person 00651036-4236-4004-88b9-11466c251548
face dffbb141-f40b-4392-8785-b6c434fa534e added to person 00651036-4236-4004-88b9-11466c251548
face 9cdac36e-5455-447b-a68d-eb1f5e2ec27d added to person 23614724-b132-407a-aaa0-67003987ce93
face d8208412-92b7-4b8d-a2f8-3926c839c87e added to person 23614724-b132-407a-aaa0-67003987ce93
Train the person group ad12b2db-d892-48ec-837a-0e7168c18224
The person group ad12b2db-d892-48ec-837a-0e7168c18224 is trained successfully.
Pausing for 60 seconds to avoid triggering rate limit on free account...
Identifying faces in image
Person is identified for face ID bc52405a-5d83-4500-9218-557468ccdf99 in image, with a confidence of 0.96726.
verification result: True. confidence: 0.96726
Person is identified for face ID dfcc3fc8-6252-4f3a-8205-71466f39d1a7 in image, with a confidence of 0.96925.
verification result: True. confidence: 0.96925
No person identified for face ID 401c581b-a178-45ed-8205-7692f6eede88 in image.
Person is identified for face ID 8809d9c7-e362-4727-8c95-e1e44f5c2e8a in image, with a confidence of 0.92898.
verification result: True. confidence: 0.92898

The person group ad12b2db-d892-48ec-837a-0e7168c18224 is deleted.

End of quickstart.

리소스 정리

Azure AI 서비스 구독을 정리하고 제거하려면 리소스 또는 리소스 그룹을 삭제할 수 있습니다. 리소스 그룹을 삭제하면 해당 리소스 그룹에 연결된 다른 모든 리소스가 함께 삭제됩니다.

다음 단계

이 빠른 시작에서는 Python용 Face 클라이언트 라이브러리를 사용하여 기본 얼굴 식별을 수행하는 방법을 알아보았습니다. 다음으로, 다양한 얼굴 감지 모델과 사용 사례에 적합한 모델을 지정하는 방법을 알아봅니다.

Java용 Face 클라이언트 라이브러리를 사용하여 얼굴 인식을 시작하세요. 이러한 단계에 따라 패키지를 설치하고 기본 작업을 위한 예제 코드를 사용해 봅니다. Face 서비스는 이미지에서 사람의 얼굴을 감지하고 인식하기 위한 고급 알고리즘에 대한 액세스를 제공합니다. 다음 단계에 따라 패키지를 설치하고 원격 이미지를 사용하여 기본 얼굴 식별을 위한 예제 코드를 사용해봅니다.

참조 설명서 | 라이브러리 소스 코드 | 패키지(Maven) | 샘플

필수 조건

  • Azure 구독 - 체험 구독 만들기
  • JDK(Java Development Kit)의 현재 버전
  • Apache Maven이 설치되었습니다. Linux에서는 가능한 경우 배포 리포지토리에서 설치합니다.
  • Azure 구독을 보유한 후에는 Azure Portal에서 Face 리소스를 만들어 키와 엔드포인트를 가져옵니다. 배포 후 리소스로 이동을 선택합니다.
    • 애플리케이션을 Face API에 연결하려면 생성한 리소스의 키와 엔드포인트가 필요합니다.
    • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

환경 변수 만들기

이 예제에서는 애플리케이션을 실행하는 로컬 컴퓨터의 환경 변수에 자격 증명을 작성합니다.

Azure Portal로 이동합니다. 필수 구성 요소 섹션에서 만든 리소스가 성공적으로 배포된 경우 다음 단계 아래에서 리소스로 이동을 선택합니다. 리소스 관리 아래에 있는 리소스의 키 및 엔드포인트 페이지에서 키 및 엔드포인트를 찾을 수 있습니다. 리소스 키는 Azure 구독 ID와 동일하지 않습니다.

키 및 엔드포인트에 대한 환경 변수를 설정하려면 콘솔 창을 열고 운영 체제 및 개발 환경에 대한 지침을 따릅니다.

  • FACE_APIKEY 환경 변수를 설정하려면 <your_key>를 리소스에 대한 키 중 하나로 바꿉니다.
  • FACE_ENDPOINT 환경 변수를 설정하려면 <your_endpoint>를 리소스에 대한 엔드포인트로 바꿉니다.

Important

API 키를 사용하는 경우 Azure Key Vault와 같은 다른 위치에 안전하게 저장합니다. API 키를 코드에 직접 포함하지 말고, 공개적으로 게시하지 마세요.

AI 서비스 보안에 대한 자세한 내용은 Azure AI 서비스에 대한 요청 인증을 참조하세요.

setx FACE_APIKEY <your_key>
setx FACE_ENDPOINT <your_endpoint>

환경 변수가 추가되면 콘솔 창을 포함하여 환경 변수를 읽는 실행 중인 프로그램을 다시 시작해야 할 수 있습니다.

얼굴 식별 및 확인

  1. 클라이언트 라이브러리 설치

    콘솔 창을 열고 빠른 시작 애플리케이션을 위한 새 폴더를 만듭니다. 다음 콘텐츠를 새 파일에 복사하세요. 프로젝트 디렉터리에 파일을 pom.xml(으)로 저장하세요.

    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example</groupId>
      <artifactId>my-application-name</artifactId>
      <version>1.0.0</version>
      <dependencies>
        <!-- https://mvnrepository.com/artifact/com.azure/azure-ai-vision-face -->
        <dependency>
          <groupId>com.azure</groupId>
          <artifactId>azure-ai-vision-face</artifactId>
          <version>1.0.0-beta.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
          <version>4.5.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
          <groupId>com.google.code.gson</groupId>
          <artifactId>gson</artifactId>
          <version>2.11.0</version>
        </dependency>
      </dependencies>
    </project>
    

    프로젝트 디렉터리에서 다음을 실행하여 SDK 및 종속성을 설치합니다.

    mvn clean dependency:copy-dependencies
    
  2. 새 Java 애플리케이션 만들기

    Quickstart.java라는 이름의 파일을 만들고 텍스트 편집기에서 열고 다음 코드를 붙여넣습니다.

    참고 항목

    접수 양식을 사용하여 Face 서비스에 대한 액세스 권한을 받지 못한 경우 이러한 기능 중 일부는 작동하지 않습니다.

    import java.util.Arrays;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    import java.util.UUID;
    
    import com.azure.ai.vision.face.FaceClient;
    import com.azure.ai.vision.face.FaceClientBuilder;
    import com.azure.ai.vision.face.models.DetectOptions;
    import com.azure.ai.vision.face.models.FaceAttributeType;
    import com.azure.ai.vision.face.models.FaceDetectionModel;
    import com.azure.ai.vision.face.models.FaceDetectionResult;
    import com.azure.ai.vision.face.models.FaceRecognitionModel;
    import com.azure.ai.vision.face.models.QualityForRecognition;
    import com.azure.core.credential.KeyCredential;
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    
    import org.apache.http.HttpHeaders;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpDelete;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.methods.HttpPut;
    import org.apache.http.client.utils.URIBuilder;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.message.BasicHeader;
    import org.apache.http.util.EntityUtils;
    
    public class Quickstart {
        // LARGE_PERSON_GROUP_ID should be all lowercase and alphanumeric. For example, 'mygroupname' (dashes are OK).
        private static final String LARGE_PERSON_GROUP_ID = UUID.randomUUID().toString();
    
        // URL path for the images.
        private static final String IMAGE_BASE_URL = "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/";
    
        // From your Face subscription in the Azure portal, get your subscription key and endpoint.
        private static final String SUBSCRIPTION_KEY = System.getenv("FACE_APIKEY");
        private static final String ENDPOINT = System.getenv("FACE_ENDPOINT");
    
        public static void main(String[] args) throws Exception {
            // 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.
            FaceRecognitionModel RECOGNITION_MODEL4 = FaceRecognitionModel.RECOGNITION_04;
    
            // Authenticate.
            FaceClient client = authenticate(ENDPOINT, SUBSCRIPTION_KEY);
    
            // Identify - recognize a face(s) in a large person group (a large person group is created in this example).
            identifyInLargePersonGroup(client, IMAGE_BASE_URL, RECOGNITION_MODEL4);
    
            System.out.println("End of quickstart.");
        }
    
        /*
         *	AUTHENTICATE
         *	Uses subscription key and region to create a client.
         */
        public static FaceClient authenticate(String endpoint, String key) {
            return new FaceClientBuilder().endpoint(endpoint).credential(new KeyCredential(key)).buildClient();
        }
    
    
        // Detect faces from image url for recognition purposes. This is a helper method for other functions in this quickstart.
        // Parameter `returnFaceId` of `DetectOptions` must be set to `true` (by default) for recognition purposes.
        // Parameter `returnFaceAttributes` is set to include the QualityForRecognition attribute. 
        // Recognition model must be set to recognition_03 or recognition_04 as a result.
        // Result faces with insufficient quality for recognition are filtered out. 
        // The field `faceId` in returned `DetectedFace`s will be used in Verify and Identify.
        // It will expire 24 hours after the detection call.
        private static List<FaceDetectionResult> detectFaceRecognize(FaceClient faceClient, String url, FaceRecognitionModel recognitionModel) {
            // Detect faces from image URL.
            DetectOptions options = new DetectOptions(FaceDetectionModel.DETECTION_03, recognitionModel, true).setReturnFaceAttributes(Arrays.asList(FaceAttributeType.QUALITY_FOR_RECOGNITION));
            List<FaceDetectionResult> detectedFaces = faceClient.detect(url, options);
            List<FaceDetectionResult> sufficientQualityFaces = detectedFaces.stream().filter(f -> f.getFaceAttributes().getQualityForRecognition() != QualityForRecognition.LOW).collect(Collectors.toList());
            System.out.println(detectedFaces.size() + " face(s) with " + sufficientQualityFaces.size() + " having sufficient quality for recognition.");
    
            return sufficientQualityFaces;
        }
    
        /*
         * IDENTIFY FACES
         * To identify faces, you need to create and define a large person group.
         * The Identify operation takes one or several face IDs from DetectedFace or PersistedFace and a LargePersonGroup and returns
         * a list of Person objects that each face might belong to. Returned Person objects are wrapped as Candidate objects,
         * which have a prediction confidence value.
         */
        public static void identifyInLargePersonGroup(FaceClient client, String url, FaceRecognitionModel recognitionModel) throws Exception {
            System.out.println("========IDENTIFY FACES========");
            System.out.println();
    
            // Create a dictionary for all your images, grouping similar ones under the same key.
            Map<String, String[]> personDictionary = new LinkedHashMap<String, String[]>();
            personDictionary.put("Family1-Dad", new String[]{"Family1-Dad1.jpg", "Family1-Dad2.jpg"});
            personDictionary.put("Family1-Mom", new String[]{"Family1-Mom1.jpg", "Family1-Mom2.jpg"});
            personDictionary.put("Family1-Son", new String[]{"Family1-Son1.jpg", "Family1-Son2.jpg"});
            // A group photo that includes some of the persons you seek to identify from your dictionary.
            String sourceImageFileName = "identification1.jpg";
    
            // Create a large person group.
            System.out.println("Create a person group (" + LARGE_PERSON_GROUP_ID + ").");
            List<BasicHeader> headers = Arrays.asList(new BasicHeader("Ocp-Apim-Subscription-Key", SUBSCRIPTION_KEY), new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json"));
            HttpClient httpClient = HttpClients.custom().setDefaultHeaders(headers).build();
            createLargePersonGroup(httpClient, recognitionModel);
            // The similar faces will be grouped into a single large person group person.
            for (String groupedFace : personDictionary.keySet()) {
                // Limit TPS
                Thread.sleep(250);
                String personId = createLargePersonGroupPerson(httpClient, groupedFace);
                System.out.println("Create a person group person '" + groupedFace + "'.");
    
                // Add face to the large person group person.
                for (String similarImage : personDictionary.get(groupedFace)) {
                    System.out.println("Check whether image is of sufficient quality for recognition");
                    DetectOptions options = new DetectOptions(FaceDetectionModel.DETECTION_03, recognitionModel, false).setReturnFaceAttributes(Arrays.asList(FaceAttributeType.QUALITY_FOR_RECOGNITION));
                    List<FaceDetectionResult> detectedFaces1 = client.detect(url + similarImage, options);
                    if (detectedFaces1.stream().anyMatch(f -> f.getFaceAttributes().getQualityForRecognition() != QualityForRecognition.HIGH)) {
                        continue;
                    }
    
                    if (detectedFaces1.size() != 1) {
                        continue;
                    }
    
                    // add face to the large person group
                    System.out.println("Add face to the person group person(" + groupedFace + ") from image `" + similarImage + "`");
                    addFaceToLargePersonGroup(httpClient, personId, url + similarImage);
                }
            }
    
            // Start to train the large person group.
            System.out.println();
            System.out.println("Train person group " + LARGE_PERSON_GROUP_ID + ".");
            trainLargePersonGroup(httpClient);
    
            // Wait until the training is completed.
            while (true) {
                Thread.sleep(1000);
                String trainingStatus = getLargePersonGroupTrainingStatus(httpClient);
                System.out.println("Training status: " + trainingStatus + ".");
                if ("succeeded".equals(trainingStatus)) {
                    break;
                }
            }
            System.out.println();
    
            System.out.println("Pausing for 60 seconds to avoid triggering rate limit on free account...");
            Thread.sleep(60000);
    
            // Detect faces from source image url.
            List<FaceDetectionResult> detectedFaces = detectFaceRecognize(client, url + sourceImageFileName, recognitionModel);
            // Add detected faceId to sourceFaceIds.
            List<String> sourceFaceIds = detectedFaces.stream().map(FaceDetectionResult::getFaceId).collect(Collectors.toList());
    
            // Identify the faces in a large person group.
            List<Map<String, Object>> identifyResults = identifyFacesInLargePersonGroup(httpClient, sourceFaceIds);
    
            for (Map<String, Object> identifyResult : identifyResults) {
                String faceId = identifyResult.get("faceId").toString();
                List<Map<String, Object>> candidates = new Gson().fromJson(new Gson().toJson(identifyResult.get("candidates")), new TypeToken<List<Map<String, Object>>>(){});
                if (candidates.isEmpty()) {
                    System.out.println("No person is identified for the face in: " + sourceImageFileName + " - " + faceId + ".");
                    continue;
                }
    
                Map<String, Object> candidate = candidates.stream().findFirst().orElseThrow();
                String personName = getLargePersonGroupPersonName(httpClient, candidate.get("personId").toString());
                System.out.println("Person '" + personName + "' is identified for the face in: " + sourceImageFileName + " - " + faceId + ", confidence: " + candidate.get("confidence") + ".");
    
                Map<String, Object> verifyResult = verifyFaceWithLargePersonGroupPerson(httpClient, faceId, candidate.get("personId").toString());
                System.out.println("Verification result: is a match? " + verifyResult.get("isIdentical") + ". confidence: " + verifyResult.get("confidence"));
            }
            System.out.println();
    
            // Delete large person group.
            System.out.println("========DELETE PERSON GROUP========");
            System.out.println();
            deleteLargePersonGroup(httpClient);
            System.out.println("Deleted the person group " + LARGE_PERSON_GROUP_ID + ".");
            System.out.println();
        }
    
        private static void createLargePersonGroup(HttpClient httpClient, FaceRecognitionModel recognitionModel) throws Exception {
            HttpPut request = new HttpPut(new URIBuilder(ENDPOINT + "/face/v1.0/largepersongroups/" + LARGE_PERSON_GROUP_ID).build());
            request.setEntity(new StringEntity(new Gson().toJson(Map.of("name", LARGE_PERSON_GROUP_ID, "recognitionModel", recognitionModel.toString()))));
            httpClient.execute(request);
            request.releaseConnection();
        }
    
        private static String createLargePersonGroupPerson(HttpClient httpClient, String name) throws Exception {
            HttpPost request = new HttpPost(new URIBuilder(ENDPOINT + "/face/v1.0/largepersongroups/" + LARGE_PERSON_GROUP_ID + "/persons").build());
            request.setEntity(new StringEntity(new Gson().toJson(Map.of("name", name))));
            String response = EntityUtils.toString(httpClient.execute(request).getEntity());
            request.releaseConnection();
            return new Gson().fromJson(response, new TypeToken<Map<String, Object>>(){}).get("personId").toString();
        }
    
        private static void addFaceToLargePersonGroup(HttpClient httpClient, String personId, String url) throws Exception {
            URIBuilder builder = new URIBuilder(ENDPOINT + "/face/v1.0/largepersongroups/" + LARGE_PERSON_GROUP_ID + "/persons/" + personId + "/persistedfaces");
            builder.setParameter("detectionModel", "detection_03");
            HttpPost request = new HttpPost(builder.build());
            request.setEntity(new StringEntity(new Gson().toJson(Map.of("url", url))));
            httpClient.execute(request);
            request.releaseConnection();
        }
    
        private static void trainLargePersonGroup(HttpClient httpClient) throws Exception {
            HttpPost request = new HttpPost(new URIBuilder(ENDPOINT + "/face/v1.0/largepersongroups/" + LARGE_PERSON_GROUP_ID + "/train").build());
            httpClient.execute(request);
            request.releaseConnection();
        }
    
        private static String getLargePersonGroupTrainingStatus(HttpClient httpClient) throws Exception {
            HttpGet request = new HttpGet(new URIBuilder(ENDPOINT + "/face/v1.0/largepersongroups/" + LARGE_PERSON_GROUP_ID + "/training").build());
            String response = EntityUtils.toString(httpClient.execute(request).getEntity());
            request.releaseConnection();
            return new Gson().fromJson(response, new TypeToken<Map<String, Object>>(){}).get("status").toString();
        }
    
        private static List<Map<String, Object>> identifyFacesInLargePersonGroup(HttpClient httpClient, List<String> sourceFaceIds) throws Exception {
            HttpPost request = new HttpPost(new URIBuilder(ENDPOINT + "/face/v1.0/identify").build());
            request.setEntity(new StringEntity(new Gson().toJson(Map.of("faceIds", sourceFaceIds, "largePersonGroupId", LARGE_PERSON_GROUP_ID))));
            String response = EntityUtils.toString(httpClient.execute(request).getEntity());
            request.releaseConnection();
            return new Gson().fromJson(response, new TypeToken<List<Map<String, Object>>>(){});
        }
    
        private static String getLargePersonGroupPersonName(HttpClient httpClient, String personId) throws Exception {
            HttpGet request = new HttpGet(new URIBuilder(ENDPOINT + "/face/v1.0/largepersongroups/" + LARGE_PERSON_GROUP_ID + "/persons/" + personId).build());
            String response = EntityUtils.toString(httpClient.execute(request).getEntity());
            request.releaseConnection();
            return new Gson().fromJson(response, new TypeToken<Map<String, Object>>(){}).get("name").toString();
        }
    
        private static Map<String, Object> verifyFaceWithLargePersonGroupPerson(HttpClient httpClient, String faceId, String personId) throws Exception {
            HttpPost request = new HttpPost(new URIBuilder(ENDPOINT + "/face/v1.0/verify").build());
            request.setEntity(new StringEntity(new Gson().toJson(Map.of("faceId", faceId, "personId", personId, "largePersonGroupId", LARGE_PERSON_GROUP_ID))));
            String response = EntityUtils.toString(httpClient.execute(request).getEntity());
            request.releaseConnection();
            return new Gson().fromJson(response, new TypeToken<Map<String, Object>>(){});
        }
    
        private static void deleteLargePersonGroup(HttpClient httpClient) throws Exception {
            HttpDelete request = new HttpDelete(new URIBuilder(ENDPOINT + "/face/v1.0/largepersongroups/" + LARGE_PERSON_GROUP_ID).build());
            httpClient.execute(request);
            request.releaseConnection();
        }
    }
    
  3. javacjava 명령을 사용하여 애플리케이션 디렉터리에서 얼굴 인식 앱을 실행하세요.

    javac -cp target\dependency\* Quickstart.java
    java -cp .;target\dependency\* Quickstart
    

출력

========IDENTIFY FACES========

Create a person group (3761e61a-16b2-4503-ad29-ed34c58ba676).
Create a person group person 'Family1-Dad'.
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Dad) from image `Family1-Dad1.jpg`
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Dad) from image `Family1-Dad2.jpg`
Create a person group person 'Family1-Mom'.
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Mom) from image `Family1-Mom1.jpg`
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Mom) from image `Family1-Mom2.jpg`
Create a person group person 'Family1-Son'.
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Son) from image `Family1-Son1.jpg`
Check whether image is of sufficient quality for recognition
Add face to the person group person(Family1-Son) from image `Family1-Son2.jpg`

Train person group 3761e61a-16b2-4503-ad29-ed34c58ba676.
Training status: succeeded.

Pausing for 60 seconds to avoid triggering rate limit on free account...
4 face(s) with 4 having sufficient quality for recognition.
Person 'Family1-Dad' is identified for the face in: identification1.jpg - d7995b34-1b72-47fe-82b6-e9877ed2578d, confidence: 0.96807.
Verification result: is a match? true. confidence: 0.96807
Person 'Family1-Mom' is identified for the face in: identification1.jpg - 844da0ed-4890-4bbf-a531-e638797f96fc, confidence: 0.96902.
Verification result: is a match? true. confidence: 0.96902
No person is identified for the face in: identification1.jpg - c543159a-57f3-4872-83ce-2d4a733d71c9.
Person 'Family1-Son' is identified for the face in: identification1.jpg - 414fac6c-7381-4dba-9c8b-fd26d52e879b, confidence: 0.9281.
Verification result: is a match? true. confidence: 0.9281

========DELETE PERSON GROUP========

Deleted the person group 3761e61a-16b2-4503-ad29-ed34c58ba676.

End of quickstart.

리소스 정리

Azure AI 서비스 구독을 정리하고 제거하려면 리소스 또는 리소스 그룹을 삭제할 수 있습니다. 리소스 그룹을 삭제하면 해당 리소스 그룹에 연결된 다른 모든 리소스가 함께 삭제됩니다.

다음 단계

이 빠른 시작에서는 Java용 Face 클라이언트 라이브러리를 사용하여 기본 얼굴 식별을 수행하는 방법을 알아보았습니다. 다음으로, 다양한 얼굴 감지 모델과 사용 사례에 적합한 모델을 지정하는 방법을 알아봅니다.

JavaScript용 Face 클라이언트 라이브러리를 사용하여 얼굴 인식을 시작합니다. 이러한 단계에 따라 패키지를 설치하고 기본 작업을 위한 예제 코드를 사용해 봅니다. Face 서비스는 이미지에서 사람의 얼굴을 감지하고 인식하기 위한 고급 알고리즘에 대한 액세스를 제공합니다. 다음 단계에 따라 패키지를 설치하고 원격 이미지를 사용하여 기본 얼굴 식별을 위한 예제 코드를 사용해봅니다.

참조 설명서 | 라이브러리 소스 코드 | 패키지(npm) | 샘플

필수 조건

  • Azure 구독 - 체험 구독 만들기
  • 최신 버전의 Node.js
  • Azure 구독을 보유한 후에는 Azure Portal에서 Face 리소스를 만들어 키와 엔드포인트를 가져옵니다. 배포 후 리소스로 이동을 선택합니다.
    • 애플리케이션을 Face API에 연결하려면 생성한 리소스의 키와 엔드포인트가 필요합니다.
    • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.

환경 변수 만들기

이 예제에서는 애플리케이션을 실행하는 로컬 컴퓨터의 환경 변수에 자격 증명을 작성합니다.

Azure Portal로 이동합니다. 필수 구성 요소 섹션에서 만든 리소스가 성공적으로 배포된 경우 다음 단계 아래에서 리소스로 이동을 선택합니다. 리소스 관리 아래에 있는 리소스의 키 및 엔드포인트 페이지에서 키 및 엔드포인트를 찾을 수 있습니다. 리소스 키는 Azure 구독 ID와 동일하지 않습니다.

키 및 엔드포인트에 대한 환경 변수를 설정하려면 콘솔 창을 열고 운영 체제 및 개발 환경에 대한 지침을 따릅니다.

  • FACE_APIKEY 환경 변수를 설정하려면 <your_key>를 리소스에 대한 키 중 하나로 바꿉니다.
  • FACE_ENDPOINT 환경 변수를 설정하려면 <your_endpoint>를 리소스에 대한 엔드포인트로 바꿉니다.

Important

API 키를 사용하는 경우 Azure Key Vault와 같은 다른 위치에 안전하게 저장합니다. API 키를 코드에 직접 포함하지 말고, 공개적으로 게시하지 마세요.

AI 서비스 보안에 대한 자세한 내용은 Azure AI 서비스에 대한 요청 인증을 참조하세요.

setx FACE_APIKEY <your_key>
setx FACE_ENDPOINT <your_endpoint>

환경 변수가 추가되면 콘솔 창을 포함하여 환경 변수를 읽는 실행 중인 프로그램을 다시 시작해야 할 수 있습니다.

얼굴 식별 및 확인

  1. 새 Node.js 애플리케이션 만들기

    콘솔 창(예: cmd, PowerShell 또는 Bash)에서 앱에 대한 새 디렉터리를 만들고 이 디렉터리로 이동합니다.

    mkdir myapp && cd myapp
    

    package.json 파일을 사용하여 노드 애플리케이션을 만들려면 npm init 명령을 실행합니다.

    npm init
    
  2. @azure-rest/ai-vision-face npm 패키지 설치:

    npm install @azure-rest/ai-vision-face
    

    앱의 package.json 파일이 종속성으로 업데이트됩니다.

  3. index.js라는 이름의 파일을 만들고 텍스트 편집기에서 열고 다음 코드를 붙여넣습니다.

    참고 항목

    접수 양식을 사용하여 Face 서비스에 대한 액세스 권한을 받지 못한 경우 이러한 기능 중 일부는 작동하지 않습니다.

    const { randomUUID } = require("crypto");
    
    const { AzureKeyCredential } = require("@azure/core-auth");
    
    const createFaceClient = require("@azure-rest/ai-vision-face").default,
      { getLongRunningPoller } = require("@azure-rest/ai-vision-face");
    
    const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
    
    const main = async () => {
      const endpoint = process.env["FACE_ENDPOINT"] ?? "<endpoint>";
      const apikey = process.env["FACE_APIKEY"] ?? "<apikey>";
      const credential = new AzureKeyCredential(apikey);
      const client = createFaceClient(endpoint, credential);
    
      const imageBaseUrl =
        "https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/";
      const largePersonGroupId = randomUUID();
    
      console.log("========IDENTIFY FACES========");
      console.log();
    
      // Create a dictionary for all your images, grouping similar ones under the same key.
      const personDictionary = {
        "Family1-Dad": ["Family1-Dad1.jpg", "Family1-Dad2.jpg"],
        "Family1-Mom": ["Family1-Mom1.jpg", "Family1-Mom2.jpg"],
        "Family1-Son": ["Family1-Son1.jpg", "Family1-Son2.jpg"],
      };
    
      // A group photo that includes some of the persons you seek to identify from your dictionary.
      const sourceImageFileName = "identification1.jpg";
    
      // Create a large person group.
      console.log(`Creating a person group with ID: ${largePersonGroupId}`);
      await client.path("/largepersongroups/{largePersonGroupId}", largePersonGroupId).put({
        body: {
          name: largePersonGroupId,
          recognitionModel: "recognition_04",
        },
      });
    
      // The similar faces will be grouped into a single large person group person.
      console.log("Adding faces to person group...");
      await Promise.all(
        Object.keys(personDictionary).map(async (name) => {
          console.log(`Create a persongroup person: ${name}`);
          const createLargePersonGroupPersonResponse = await client
            .path("/largepersongroups/{largePersonGroupId}/persons", largePersonGroupId)
            .post({
              body: { name },
            });
    
          const { personId } = createLargePersonGroupPersonResponse.body;
    
          await Promise.all(
            personDictionary[name].map(async (similarImage) => {
              // Check if the image is of sufficent quality for recognition.
              const detectResponse = await client.path("/detect").post({
                contentType: "application/json",
                queryParameters: {
                  detectionModel: "detection_03",
                  recognitionModel: "recognition_04",
                  returnFaceId: false,
                  returnFaceAttributes: ["qualityForRecognition"],
                },
                body: { url: `${imageBaseUrl}${similarImage}` },
              });
    
              const sufficientQuality = detectResponse.body.every(
                (face) => face.faceAttributes?.qualityForRecognition === "high",
              );
              if (!sufficientQuality) {
                return;
              }
    
              if (detectResponse.body.length != 1) {
                return;
              }
    
              // Quality is sufficent, add to group.
              console.log(
                `Add face to the person group person: (${name}) from image: (${similarImage})`,
              );
              await client
                .path(
                  "/largepersongroups/{largePersonGroupId}/persons/{personId}/persistedfaces",
                  largePersonGroupId,
                  personId,
                )
                .post({
                  queryParameters: { detectionModel: "detection_03" },
                  body: { url: `${imageBaseUrl}${similarImage}` },
                });
            }),
          );
        }),
      );
      console.log("Done adding faces to person group.");
    
      // Start to train the large person group.
      console.log();
      console.log(`Training person group: ${largePersonGroupId}`);
      const trainResponse = await client
        .path("/largepersongroups/{largePersonGroupId}/train", largePersonGroupId)
        .post();
      const poller = await getLongRunningPoller(client, trainResponse);
      await poller.pollUntilDone();
      console.log(`Training status: ${poller.getOperationState().status}`);
      if (poller.getOperationState().status !== "succeeded") {
        return;
      }
    
      console.log("Pausing for 60 seconds to avoid triggering rate limit on free account...");
      await sleep(60000);
    
      // Detect faces from source image url and only take those with sufficient quality for recognition.
      const detectResponse = await client.path("/detect").post({
        contentType: "application/json",
        queryParameters: {
          detectionModel: "detection_03",
          recognitionModel: "recognition_04",
          returnFaceId: true,
          returnFaceAttributes: ["qualityForRecognition"],
        },
        body: { url: `${imageBaseUrl}${sourceImageFileName}` },
      });
      const faceIds = detectResponse.body.filter((face) => face.faceAttributes?.qualityForRecognition !== "low").map((face) => face.faceId);
    
      // Identify the faces in a large person group.
      const identifyResponse = await client.path("/identify").post({
        body: { faceIds, largePersonGroupId: largePersonGroupId },
      });
      await Promise.all(
        identifyResponse.body.map(async (result) => {
          try {
            const getLargePersonGroupPersonResponse = await client
              .path(
                "/largepersongroups/{largePersonGroupId}/persons/{personId}",
                largePersonGroupId,
                result.candidates[0].personId,
              )
              .get();
            const person = getLargePersonGroupPersonResponse.body;
            console.log(
              `Person: ${person.name} is identified for face in: ${sourceImageFileName} with ID: ${result.faceId}. Confidence: ${result.candidates[0].confidence}`,
            );
    
            // Verification:
            const verifyResponse = await client.path("/verify").post({
              body: {
                faceId: result.faceId,
                largePersonGroupId: largePersonGroupId,
                personId: person.personId,
              },
            });
            console.log(
              `Verification result between face ${result.faceId} and person ${person.personId}: ${verifyResponse.body.isIdentical} with confidence: ${verifyResponse.body.confidence}`,
            );
          } catch (error) {
            console.log(`No persons identified for face with ID ${result.faceId}`);
          }
        }),
      );
      console.log();
    
      // Delete large person group.
      console.log(`Deleting person group: ${largePersonGroupId}`);
      await client.path("/largepersongroups/{largePersonGroupId}", largePersonGroupId).delete();
      console.log();
    
      console.log("Done.");
    };
    
    main().catch(console.error);
    
  4. quickstart 파일의 node 명령을 사용하여 애플리케이션을 실행합니다.

    node index.js
    

출력

========IDENTIFY FACES========

Creating a person group with ID: a230ac8b-09b2-4fa0-ae04-d76356d88d9f
Adding faces to person group...
Create a persongroup person: Family1-Dad
Create a persongroup person: Family1-Mom
Create a persongroup person: Family1-Son
Add face to the person group person: (Family1-Dad) from image: (Family1-Dad1.jpg)
Add face to the person group person: (Family1-Mom) from image: (Family1-Mom1.jpg)
Add face to the person group person: (Family1-Son) from image: (Family1-Son1.jpg)
Add face to the person group person: (Family1-Dad) from image: (Family1-Dad2.jpg)
Add face to the person group person: (Family1-Mom) from image: (Family1-Mom2.jpg)
Add face to the person group person: (Family1-Son) from image: (Family1-Son2.jpg)
Done adding faces to person group.

Training person group: a230ac8b-09b2-4fa0-ae04-d76356d88d9f
Training status: succeeded
Pausing for 60 seconds to avoid triggering rate limit on free account...
No persons identified for face with ID 56380623-8bf0-414a-b9d9-c2373386b7be
Person: Family1-Dad is identified for face in: identification1.jpg with ID: c45052eb-a910-4fd3-b1c3-f91ccccc316a. Confidence: 0.96807
Person: Family1-Son is identified for face in: identification1.jpg with ID: 8dce9b50-513f-4fe2-9e19-352acfd622b3. Confidence: 0.9281
Person: Family1-Mom is identified for face in: identification1.jpg with ID: 75868da3-66f6-4b5f-a172-0b619f4d74c1. Confidence: 0.96902
Verification result between face c45052eb-a910-4fd3-b1c3-f91ccccc316a and person 35a58d14-fd58-4146-9669-82ed664da357: true with confidence: 0.96807
Verification result between face 8dce9b50-513f-4fe2-9e19-352acfd622b3 and person 2d4d196c-5349-431c-bf0c-f1d7aaa180ba: true with confidence: 0.9281
Verification result between face 75868da3-66f6-4b5f-a172-0b619f4d74c1 and person 35d5de9e-5f92-4552-8907-0d0aac889c3e: true with confidence: 0.96902

Deleting person group: a230ac8b-09b2-4fa0-ae04-d76356d88d9f

Done.

리소스 정리

Azure AI 서비스 구독을 정리하고 제거하려면 리소스 또는 리소스 그룹을 삭제할 수 있습니다. 리소스 그룹을 삭제하면 해당 리소스 그룹에 연결된 다른 모든 리소스가 함께 삭제됩니다.

다음 단계

이 빠른 시작에서는 JavaScript용 Face 클라이언트 라이브러리를 사용하여 기본 얼굴 식별을 수행하는 방법을 알아보았습니다. 다음으로, 다양한 얼굴 감지 모델과 사용 사례에 적합한 모델을 지정하는 방법을 알아봅니다.

Face REST API를 사용하여 얼굴 인식을 시작합니다. Face 서비스는 이미지에서 사람의 얼굴을 감지하고 인식하기 위한 고급 알고리즘에 대한 액세스를 제공합니다.

참고 항목

이 빠른 시작에서는 cURL 명령을 사용하여 REST API를 호출합니다. 프로그래밍 언어를 사용하여 REST API를 호출할 수도 있습니다. 얼굴 식별과 같은 복잡한 시나리오는 언어 SDK를 사용하여 구현하는 것이 더 쉽습니다. C#, Python, Java, JavaScript, Go의 예는 GitHub 샘플을 참조하세요.

필수 조건

  • Azure 구독 - 체험 구독 만들기
  • Azure 구독을 보유한 후에는 Azure Portal에서 Face 리소스를 만들어 키와 엔드포인트를 가져옵니다. 배포 후 리소스로 이동을 선택합니다.
    • 애플리케이션을 Face API에 연결하려면 생성한 리소스의 키와 엔드포인트가 필요합니다. 이 빠른 시작의 뒷부분에 나오는 코드에 키와 엔드포인트를 붙여넣습니다.
    • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.
  • PowerShell 버전 6.0 이상 또는 유사한 명령줄 애플리케이션.
  • cURL 설치

얼굴 식별 및 확인

참고 항목

접수 양식을 사용하여 Face 서비스에 대한 액세스 권한을 받지 못한 경우 이러한 기능 중 일부는 작동하지 않습니다.

  1. 먼저 원본 얼굴에서 검색 Detect API를 호출합니다. 이는 더 큰 그룹에서 식별하려고 시도할 얼굴입니다. 다음 명령을 텍스트 편집기에 복사하고, 자체 키 및 엔드포인트를 삽입한 다음, 셸 창에 복사하여 실행합니다.

    curl.exe -v -X POST "https://{resource endpoint}/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&recognitionModel=recognition_04&returnRecognitionModel=false&detectionModel=detection_03&faceIdTimeToLive=86400" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription key}" --data-ascii "{""url"":""https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/identification1.jpg""}"
    

    반환된 얼굴 ID 문자열을 임시 위치에 저장합니다. 마지막에 다시 사용하게 됩니다.

  2. 다음으로 LargePersonGroup을 만들고 정규식 패턴 ^[a-z0-9-_]+$와 일치하는 임의의 ID를 제공해야 합니다. 이 개체는 여러 사람의 집계된 얼굴 데이터를 저장합니다. 다음 명령을 실행하여 자체 키를 삽입합니다. 필요에 따라 요청 본문에서 그룹의 이름과 메타데이터를 변경합니다.

    curl.exe -v -X PUT "https://{resource endpoint}/face/v1.0/largepersongroups/{largePersonGroupId}" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription key}" --data-ascii "{
        ""name"": ""large-person-group-name"",
        ""userData"": ""User-provided data attached to the large person group."",
        ""recognitionModel"": ""recognition_04""
    }"
    

    만들어진 그룹의 지정된 ID를 임시 위치에 저장합니다.

  3. 다음으로, 그룹에 속한 Person 개체를 만듭니다. 다음 명령을 실행하여 이전 단계의 LargePersonGroup ID와 자체 키를 삽입합니다. 이 명령은 "Family1-Dad"라는 Person을 만듭니다.

    curl.exe -v -X POST "https://{resource endpoint}/face/v1.0/largepersongroups/{largePersonGroupId}/persons" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription key}" --data-ascii "{
        ""name"": ""Family1-Dad"",
        ""userData"": ""User-provided data attached to the person.""
    }"
    

    이 명령을 실행한 후 다른 입력 데이터로 다시 실행하여 더 많은 Person 개체("Family1-Mom", "Family1-Son", "Family1-Daughter", "Family2-Lady", "Family2-Man")를 만듭니다.

    만든 각 Person의 ID를 저장합니다. 어떤 사람의 이름에 어떤 ID가 있는지 추적하는 것이 중요합니다.

  4. 다음으로, 새 얼굴을 감지하고 존재하는 Person 개체와 연결해야 합니다. 다음 명령은 Family1-Dad1.jpg 이미지에서 얼굴을 감지하여 해당 인물에 추가합니다. "Family1-Dad" Person 개체를 만들 때 반환된 ID로 personId를 지정해야 합니다. 이미지 이름은 생성된 Person의 이름에 해당합니다. 또한 적절한 필드에 LargePersonGroup ID와 키를 입력합니다.

    curl.exe -v -X POST "https://{resource endpoint}/face/v1.0/largepersongroups/{largePersonGroupId}/persons/{personId}/persistedfaces?detectionModel=detection_03" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription key}" --data-ascii "{""url"":""https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/Face/images/Family1-Dad1.jpg""}"
    

    그런 다음, 다른 원본 이미지와 대상 Person을 사용하여 위의 명령을 다시 실행합니다. 사용 가능한 이미지는 Family1-Dad1.jpg, Family1-Dad2.jpg Family1-Mom1.jpg, Family1-Mom2.jpg, Family1-Son1.jpg, Family1-Son2.jpg, Family1-Daughter1.jpg, Family1-Daughter2.jpg, Family2-Lady1.jpg, Family2-Lady2.jpg, Family2-Man1.jpg, Family2-Man2.jpg입니다. API 호출에서 지정한 ID의 Person이 요청 본문에 있는 이미지 파일의 이름과 일치하는지 확인합니다.

    이 단계가 끝나면 제공된 이미지에서 직접 감지된 하나 이상의 해당 얼굴이 있는 여러 Person 개체가 있어야 합니다.

  5. 다음으로, 현재 얼굴 데이터를 사용하여 LargePersonGroup을 학습시킵니다. 학습 작업은 얼굴 특징(때로는 여러 원본 이미지에서 집계됨)을 각각의 개인과 연결하는 방법을 모델에 알려줍니다. 명령을 실행하기 전에 LargePersonGroup ID 및 키를 삽입합니다.

    curl.exe -v -X POST "https://{resource endpoint}/face/v1.0/largepersongroups/{largePersonGroupId}/train" -H "Ocp-Apim-Subscription-Key: {subscription key}" --data ""
    
  6. 학습 상태가 성공했는지 확인합니다. 그렇지 않은 경우 잠시 기다렸다가 다시 문의하세요.

    curl.exe -v "https://{resource endpoint}/face/v1.0/largepersongroups/{largePersonGroupId}/training" -H "Ocp-Apim-Subscription-Key: {subscription key}"
    
  7. 이제 첫 번째 단계의 원본 얼굴 ID와 LargePersonGroup ID를 사용하여 Identify API를 호출할 준비가 되었습니다. 이 값을 요청 본문의 적절한 필드에 삽입하고 키를 삽입합니다.

    curl.exe -v -X POST "https://{resource endpoint}/face/v1.0/identify" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: {subscription key}" --data-ascii "{
        ""largePersonGroupId"": ""INSERT_PERSONGROUP_ID"",
        ""faceIds"": [
            ""INSERT_SOURCE_FACE_ID""
        ],
        ""maxNumOfCandidatesReturned"": 1,
        ""confidenceThreshold"": 0.5
    }"
    

    응답은 원본 얼굴로 식별된 사람을 나타내는 Person ID를 제공해야 합니다. "Family1-Dad" 인물에 해당하는 ID여야 합니다. 원본 얼굴이 그 인물의 얼굴이기 때문입니다.

  8. 얼굴 확인을 수행하려면 이전 단계에서 반환된 사람 ID, LargePersonGroup ID 및 원본 얼굴 ID를 사용합니다. 이 값을 요청 본문의 필드에 삽입하고 키를 삽입합니다.

    curl.exe -v -X POST "https://{resource endpoint}/face/v1.0/verify" `
    -H "Content-Type: application/json" `
    -H "Ocp-Apim-Subscription-Key: {subscription key}" `
    --data-ascii "{
        ""faceId"": ""INSERT_SOURCE_FACE_ID"",
        ""personId"": ""INSERT_PERSON_ID"",
        ""largePersonGroupId"": ""INSERT_PERSONGROUP_ID""
    }"
    

    응답은 신뢰도 값과 함께 부울 확인 결과를 제공해야 합니다.

리소스 정리

이 연습에서 만든 LargePersonGroup을 삭제하려면 LargePersonGroup - 삭제 호출을 실행합니다.

curl.exe -v -X DELETE "https://{resource endpoint}/face/v1.0/largepersongroups/{largePersonGroupId}" -H "Ocp-Apim-Subscription-Key: {subscription key}"

Azure AI 서비스 구독을 정리하고 제거하려면 리소스 또는 리소스 그룹을 삭제할 수 있습니다. 리소스 그룹을 삭제하면 해당 리소스 그룹에 연결된 다른 모든 리소스가 함께 삭제됩니다.

다음 단계

이 빠른 시작에서는 Face REST API를 사용하여 기본 얼굴 인식 작업을 수행하는 방법을 알아보았습니다. 다음으로, 다양한 얼굴 감지 모델과 사용 사례에 적합한 모델을 지정하는 방법을 알아봅니다.