다음을 통해 공유


자습서: 얼굴의 활동성 감지

얼굴 활동성 감지를 사용하여 입력 동영상 스트림의 얼굴이 실제(라이브) 또는 가짜(스푸핑됨)인지 확인할 수 있습니다. 사기꾼이 다른 사람을 사칭하기 위해 사진, 동영상, 마스크 또는 기타 수단을 사용하여 시스템에 액세스하는 것을 방지하는 것은 생체 인식 인증 시스템의 중요한 구성 요소입니다.

활동성 감지 목표는 시스템이 인증 시 실제로 존재하는 살아 있는 사용자와 상호 작용하도록 하는 것입니다. 이러한 시스템은 디지털 재무, 원격 액세스 제어 및 온라인 ID 검증 프로세스의 증가로 인해 점점 더 중요해지고 있습니다.

Azure AI Face 활동성 감지 솔루션은 종이 인쇄물, 2d/3d 마스크 및 휴대폰과 노트북의 스푸핑 프레젠테이션에 이르기까지 다양한 스푸핑 형식으로부터 성공적으로 방어합니다. 활동성 탐지는 연구의 활성 영역으로, 시간이 지남에 따라 점점 더 정교한 스푸핑 공격에 대응하기 위해 지속적으로 개선되고 있습니다. 전체 솔루션이 새로운 형식의 공격에 대해 더 강력해짐에 따라 시간이 지남에 따라 클라이언트와 서비스 구성 요소가 지속적으로 개선됩니다.

Important

활동성을 위한 Face 클라이언트 SDK는 제어된 기능입니다. 얼굴 인식 유입 양식을 작성하여 활동성 기능에 대한 액세스를 요청해야 합니다. Azure 구독에 액세스 권한이 부여되면 Face 활동성 SDK를 다운로드할 수 있습니다.

소개

활성 솔루션 통합에는 프런트 엔드 모바일/웹 애플리케이션과 앱 서버/오케스트레이터라는 두 가지 개별 구성 요소가 포함됩니다.

Azure AI Face의 활성 워크플로 다이어그램.

  • 프런트 엔드 애플리케이션: 프런트 엔드 애플리케이션은 앱 서버로부터 권한 부여를 받아 활동성 감지를 시작합니다. 주요 목표는 카메라를 활성화하고 활동성 감지 프로세스를 통해 최종 사용자를 정확하게 안내하는 것입니다.
  • 앱 서버: 앱 서버는 활동성 감지 세션을 만들고 특정 세션에 대해 Face 서비스로부터 권한 부여 토큰을 가져오기 위한 백 엔드 서버 역할을 합니다. 이 토큰은 프런트 엔드 애플리케이션에 활동성 감지를 수행할 수 있는 권한을 부여합니다. 앱 서버의 목표는 세션을 관리하고, 프런트 엔드 애플리케이션에 대한 권한을 부여하고, 활동성 감지 프로세스의 결과를 보는 것입니다.

또한 얼굴 확인과 활동성 감지를 결합하여 그 사람이 사용자가 지정한 특정 사람인지 확인합니다. 다음 표는 활동성 감지 기능에 대한 세부 정보를 설명하는 데 도움이 됩니다.

기능 설명
활동성 감지 입력이 진짜인지 가짜인지 판단하고, 앱 서버만이 활성 확인을 시작하고 결과를 쿼리할 수 있는 권한을 갖습니다.
얼굴 인증을 사용하여 활동성 감지 입력 내용이 진짜인지 가짜인지 판단하고 제공한 참조 이미지를 기반으로 사람의 ID를 확인합니다. 앱 서버 또는 프런트 엔드 애플리케이션이 참조 이미지를 제공할 수 있습니다. 앱 서버만이 활성 확인을 초기화하고 결과를 쿼리할 수 있는 권한을 갖습니다.

이 자습서에서는 프런트 엔드 애플리케이션과 앱 서버를 작동하여 다양한 언어 SDK에서 활동성 감지얼굴 확인을 통한 활동성 감지를 수행하는 방법을 보여 줍니다.

필수 조건

  • Azure 구독 - 체험 구독 만들기
  • 책임 있는 AI 조건에 동의하고 리소스를 만들려면 Azure 계정에 Cognitive Services 기여자 역할이 할당되어 있어야 합니다. 이 역할을 계정에 할당하려면 역할 할당의 단계를 수행하거나 관리자에게 문의하세요.
  • Azure 구독을 보유한 후에는 Azure Portal에서 Face 리소스를 만들어 키와 엔드포인트를 가져옵니다. 배포 후 리소스로 이동을 선택합니다.
    • 애플리케이션을 Face 서비스에 연결하려면 생성한 리소스의 키와 엔드포인트가 필요합니다.
    • 평가판 가격 책정 계층(F0)을 통해 서비스를 사용해보고, 나중에 프로덕션용 유료 계층으로 업그레이드할 수 있습니다.
  • 모바일(IOS 및 Android) 및 웹용 Azure AI 비전 Face 클라이언트 SDK에 액세스합니다. 시작하려면 얼굴 인식 제한 액세스 기능을 신청하여 SDK에 액세스해야 합니다. 자세한 내용은 얼굴 제한 액세스 페이지를 참조하세요.

활동성 감지를 수행하도록 프런트 엔드 애플리케이션 및 앱 서버 설정

프런트 엔드 애플리케이션과 앱 서버를 위해 다양한 언어로 SDK가 제공됩니다. 프런트 엔드 애플리케이션 및 앱 서버를 설정하려면 다음 지침을 참조하세요.

프런트 엔드 애플리케이션용 SDK 다운로드

SDK에 액세스할 수 있게 되면 azure-ai-vision-sdk GitHub 리포지토리의 지침에 따라 UI와 코드를 네이티브 모바일 애플리케이션에 통합합니다. Liveness SDK는 Android 모바일 애플리케이션용 Java/Kotlin, iOS 모바일 애플리케이션용 Swift 및 웹 애플리케이션용 JavaScript를 지원합니다.

  • Swift iOS의 경우 iOS 샘플의 지침을 따릅니다.
  • Kotlin/Java Android의 경우 Android 샘플의 지침을 따릅니다.
  • JavaScript 웹의 경우 웹 샘플의 지침을 따릅니다.

애플리케이션에 코드를 추가하면 SDK는 카메라 시작, 최종 사용자의 위치 조정 안내, 활성 페이로드 구성, Azure AI Face 클라우드 서비스 호출을 처리하여 활성 페이로드를 처리합니다.

앱 서버용 Azure AI Face 클라이언트 라이브러리 다운로드

앱 서버/오케스트레이터는 활성 세션의 수명 주기를 제어하는 ​​일을 담당합니다. 앱 서버는 활동성 감지를 수행하기 전에 세션을 만들어야 하며, 그 후 결과를 쿼리하고 활성 검사가 완료되면 세션을 삭제할 수 있습니다. 사용자의 앱 서버를 쉽게 구현하기 위해 다양한 언어로 된 라이브러리를 제공합니다. 원하는 패키지를 설치하려면 다음 단계를 따릅니다.

환경 변수 만들기

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

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

코드에 키를 직접 포함하지 말고 공개적으로 게시하지 마세요. Azure Key Vault와 같은 추가 인증 옵션은 Azure AI 서비스 보안 문서를 참조하세요.

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

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

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

활동성 감지 수행

활동성 오케스트레이션과 관련된 대략적인 단계는 다음과 같습니다.

Azure AI Face의 활성 워크플로 다이어그램.

  1. 프런트 엔드 애플리케이션은 활성 확인을 시작하고 앱 서버에 알립니다.

  2. 앱 서버는 Azure AI Face Service를 사용하여 새 활동성 세션을 만듭니다. 서비스는 활동성 세션을 만들고 세션 권한 부여 토큰으로 다시 응답합니다. 활성 세션 만들기와 관련된 각 요청 매개 변수에 대한 자세한 내용은 활성 세션 만들기 작업을 참조하세요.

    var endpoint = new Uri(System.Environment.GetEnvironmentVariable("FACE_ENDPOINT"));
    var credential = new AzureKeyCredential(System.Environment.GetEnvironmentVariable("FACE_APIKEY"));
    
    var sessionClient = new FaceSessionClient(endpoint, credential);
    
    var createContent = new CreateLivenessSessionContent(LivenessOperationMode.Passive)
    {
        DeviceCorrelationId = "723d6d03-ef33-40a8-9682-23a1feb7bccd",
        SendResultsToClient = false,
    };
    
    var createResponse = await sessionClient.CreateLivenessSessionAsync(createContent);
    var sessionId = createResponse.Value.SessionId;
    Console.WriteLine($"Session created.");
    Console.WriteLine($"Session id: {sessionId}");
    Console.WriteLine($"Auth token: {createResponse.Value.AuthToken}");
    

    응답 본문의 예:

    {
        "sessionId": "a6e7193e-b638-42e9-903f-eaf60d2b40a5",
        "authToken": "<session-authorization-token>"
    }
    
  3. 앱 서버는 세션 권한 부여 토큰을 프런트 엔드 애플리케이션에 다시 제공합니다.

  4. 프런트 엔드 애플리케이션은 Azure AI 비전 SDK 초기화 중에 세션 권한 부여 토큰을 제공합니다.

    mServiceOptions?.setTokenCredential(com.azure.android.core.credential.TokenCredential { _, callback ->
        callback.onSuccess(com.azure.android.core.credential.AccessToken("<INSERT_TOKEN_HERE>", org.threeten.bp.OffsetDateTime.MAX))
    })
    
  5. 그런 다음 SDK는 카메라를 시작하고 사용자에게 올바른 위치를 지정하도록 안내한 다음 활동성 감지 서비스 엔드포인트를 호출하기 위한 페이로드를 준비합니다.

  6. SDK는 Azure AI 비전 Face 서비스를 호출하여 활동성 검색을 수행합니다. 서비스가 응답하면 SDK는 프런트 엔드 애플리케이션에 활성 확인이 완료되었음을 알립니다.

  7. 프런트 엔드 애플리케이션은 활성 확인 완료를 앱 서버에 전달합니다.

  8. 이제 앱 서버는 Azure AI 비전 Face 서비스의 활동성 검색 결과를 쿼리할 수 있습니다.

    var getResultResponse = await sessionClient.GetLivenessSessionResultAsync(sessionId);
    
    var sessionResult = getResultResponse.Value;
    Console.WriteLine($"Session id: {sessionResult.Id}");
    Console.WriteLine($"Session status: {sessionResult.Status}");
    Console.WriteLine($"Liveness detection request id: {sessionResult.Result?.RequestId}");
    Console.WriteLine($"Liveness detection received datetime: {sessionResult.Result?.ReceivedDateTime}");
    Console.WriteLine($"Liveness detection decision: {sessionResult.Result?.Response.Body.LivenessDecision}");
    Console.WriteLine($"Session created datetime: {sessionResult.CreatedDateTime}");
    Console.WriteLine($"Auth token TTL (seconds): {sessionResult.AuthTokenTimeToLiveInSeconds}");
    Console.WriteLine($"Session expired: {sessionResult.SessionExpired}");
    Console.WriteLine($"Device correlation id: {sessionResult.DeviceCorrelationId}");
    

    응답 본문의 예:

    {
        "status": "ResultAvailable",
        "result": {
            "id": 1,
            "sessionId": "a3dc62a3-49d5-45a1-886c-36e7df97499a",
            "requestId": "cb2b47dc-b2dd-49e8-bdf9-9b854c7ba843",
            "receivedDateTime": "2023-10-31T16:50:15.6311565+00:00",
            "request": {
                "url": "/face/v1.1-preview.1/detectliveness/singlemodal",
                "method": "POST",
                "contentLength": 352568,
                "contentType": "multipart/form-data; boundary=--------------------------482763481579020783621915",
                "userAgent": ""
            },
            "response": {
                "body": {
                    "livenessDecision": "realface",
                    "target": {
                        "faceRectangle": {
                            "top": 59,
                            "left": 121,
                            "width": 409,
                            "height": 395
                        },
                        "fileName": "content.bin",
                        "timeOffsetWithinFile": 0,
                        "imageType": "Color"
                    },
                    "modelVersionUsed": "2022-10-15-preview.04"
                },
                "statusCode": 200,
                "latencyInMilliseconds": 1098
            },
            "digest": "537F5CFCD8D0A7C7C909C1E0F0906BF27375C8E1B5B58A6914991C101E0B6BFC"
        },
        "id": "a3dc62a3-49d5-45a1-886c-36e7df97499a",
        "createdDateTime": "2023-10-31T16:49:33.6534925+00:00",
        "authTokenTimeToLiveInSeconds": 600,
        "deviceCorrelationId": "723d6d03-ef33-40a8-9682-23a1feb7bccd",
        "sessionExpired": false
    }
    
  9. 더 이상 결과를 쿼리하지 않으면 앱 서버가 세션을 삭제할 수 있습니다.

    await sessionClient.DeleteLivenessSessionAsync(sessionId);
    Console.WriteLine($"The session {sessionId} is deleted.");
    

얼굴인식을 사용하여 활동성 감지 수행

얼굴인식과 활동성 감지를 결합하면 관심 있는 특정인의 생체 인식 확인과 그 사람이 시스템에 실제로 존재한다는 추가 보장이 가능합니다. 활동성과 확인을 통합하는 데는 다음 두 가지 부분이 있습니다.

  1. 적절한 참조 이미지를 선택합니다.
  2. 확인을 사용하여 활동성 오케스트레이션을 설정합니다.

Azure AI Face의 얼굴 확인 워크플로 다이어그램.

적절한 참조 이미지 선택

다음과 같은 팁을 사용하여 입력 이미지가 가장 정확한 인식 결과를 제공하는지 확인합니다.

기술 요구 사항

  • 지원되는 입력 이미지 형식은 JPEG, PNG, GIF(첫 번째 프레임), BMP입니다.
  • 이미지 파일 크기는 6MB를 넘지 않아야 합니다.
  • 이미지가 얼굴 인식을 시도하기에 충분한 품질인지 여부에 대한 일반적인 지침으로 해당 검색 모델을 사용할 때 얼굴 인식 작업에서 qualityForRecognition 특성을 활용할 수 있습니다. 개인 등록에는 ""high" 품질 이미지만 권장되며 식별 시나리오에는 "medium" 이상의 품질이 권장됩니다.

컴퍼지션 요구 사항

  • 사진이 깨끗하고 선명하며, 흐릿하거나 픽셀화되거나 왜곡되거나 손상되지 않아야 합니다.
  • 얼굴 흠이나 얼굴 모양을 제거하기 위해 사진을 변경하지 않아야 합니다.
  • 사진은 RGB 색이 지원되는 형식(JPEG, PNG, WEBP, BMP)이어야 합니다. 권장되는 얼굴 크기는 200픽셀 x 200픽셀입니다. 얼굴 크기가 200픽셀 x 200픽셀보다 크면 AI 품질이 향상되지 않으며 크기가 6MB를 넘지 않아야 합니다.
  • 사용자가 안경, 마스크, 모자, 헤드폰을 착용하거나, 머리 또는 얼굴을 가리지 않아야 합니다. 얼굴에 장애물이 없어야 합니다.
  • 얼굴 장신구는 얼굴을 가리지 않는 한 허용됩니다.
  • 사진에는 얼굴이 하나만 표시되어야 합니다.
  • 얼굴은 두 눈을 뜨고, 입을 닫고, 극단적인 얼굴 표정을 짓거나 머리를 기울이지 않으며, 감정을 드러내지 않는 정면 자세를 취해야 합니다.
  • 얼굴에 그림자나 적목 현상이 없어야 합니다. 다음 중 하나라도 발생하면 사진을 다시 촬영합니다.
  • 배경은 균일하고 무늬가 없어야 하며 그림자가 없어야 합니다.
  • 얼굴이 이미지 가운데에 배치되어야 하며 이미지의 50% 이상을 차지해야 합니다.

확인을 사용하여 활동성 오케스트레이션을 설정합니다.

확인 오케스트레이션을 사용하는 활동성과 관련된 대략적인 단계는 다음과 같습니다.

  1. 다음 두 가지 방법 중 하나를 사용하여 확인 참조 이미지를 제공합니다.

    • 앱 서버는 활동성 세션을 만들 때 참조 이미지를 제공합니다. 확인을 통한 활성 세션 만들기와 관련된 각 요청 매개 변수에 대한 자세한 내용은 확인을 통한 활성 세션 만들기 작업을 참조하세요.

      var endpoint = new Uri(System.Environment.GetEnvironmentVariable("FACE_ENDPOINT"));
      var credential = new AzureKeyCredential(System.Environment.GetEnvironmentVariable("FACE_APIKEY"));
      
      var sessionClient = new FaceSessionClient(endpoint, credential);
      
      var createContent = new CreateLivenessSessionContent(LivenessOperationMode.Passive)
      {
          DeviceCorrelationId = "723d6d03-ef33-40a8-9682-23a1feb7bccd"
      };
      using var fileStream = new FileStream("test.png", FileMode.Open, FileAccess.Read);
      
      var createResponse = await sessionClient.CreateLivenessWithVerifySessionAsync(createContent, fileStream);
      
      var sessionId = createResponse.Value.SessionId;
      Console.WriteLine("Session created.");
      Console.WriteLine($"Session id: {sessionId}");
      Console.WriteLine($"Auth token: {createResponse.Value.AuthToken}");
      Console.WriteLine("The reference image:");
      Console.WriteLine($"  Face rectangle: {createResponse.Value.VerifyImage.FaceRectangle.Top}, {createResponse.Value.VerifyImage.FaceRectangle.Left}, {createResponse.Value.VerifyImage.FaceRectangle.Width}, {createResponse.Value.VerifyImage.FaceRectangle.Height}");
      Console.WriteLine($"  The quality for recognition: {createResponse.Value.VerifyImage.QualityForRecognition}");
      

      응답 본문의 예:

      {
          "verifyImage": {
              "faceRectangle": {
                  "top": 506,
                  "left": 51,
                  "width": 680,
                  "height": 475
              },
              "qualityForRecognition": "high"
          },
          "sessionId": "3847ffd3-4657-4e6c-870c-8e20de52f567",
          "authToken": "<session-authorization-token>"
      }
      
    • 프런트 엔드 애플리케이션은 SDK를 초기화할 때 참조 이미지를 제공합니다. 이 시나리오는 웹 솔루션에서 지원되지 않습니다.

      val singleFaceImageSource = VisionSource.fromFile("/path/to/image.jpg")
      mFaceAnalysisOptions?.setRecognitionMode(RecognitionMode.valueOfVerifyingMatchToFaceInSingleFaceImage(singleFaceImageSource))
      
  2. 이제 앱 서버는 활동성 결과 외에도 확인 결과를 쿼리할 수 있습니다.

    var getResultResponse = await sessionClient.GetLivenessWithVerifySessionResultAsync(sessionId);
    var sessionResult = getResultResponse.Value;
    Console.WriteLine($"Session id: {sessionResult.Id}");
    Console.WriteLine($"Session status: {sessionResult.Status}");
    Console.WriteLine($"Liveness detection request id: {sessionResult.Result?.RequestId}");
    Console.WriteLine($"Liveness detection received datetime: {sessionResult.Result?.ReceivedDateTime}");
    Console.WriteLine($"Liveness detection decision: {sessionResult.Result?.Response.Body.LivenessDecision}");
    Console.WriteLine($"Verification result: {sessionResult.Result?.Response.Body.VerifyResult.IsIdentical}");
    Console.WriteLine($"Verification confidence: {sessionResult.Result?.Response.Body.VerifyResult.MatchConfidence}");
    Console.WriteLine($"Session created datetime: {sessionResult.CreatedDateTime}");
    Console.WriteLine($"Auth token TTL (seconds): {sessionResult.AuthTokenTimeToLiveInSeconds}");
    Console.WriteLine($"Session expired: {sessionResult.SessionExpired}");
    Console.WriteLine($"Device correlation id: {sessionResult.DeviceCorrelationId}");
    

    응답 본문의 예:

    {
        "status": "ResultAvailable",
        "result": {
            "id": 1,
            "sessionId": "3847ffd3-4657-4e6c-870c-8e20de52f567",
            "requestId": "f71b855f-5bba-48f3-a441-5dbce35df291",
            "receivedDateTime": "2023-10-31T17:03:51.5859307+00:00",
            "request": {
                "url": "/face/v1.1-preview.1/detectlivenesswithverify/singlemodal",
                "method": "POST",
                "contentLength": 352568,
                "contentType": "multipart/form-data; boundary=--------------------------590588908656854647226496",
                "userAgent": ""
            },
            "response": {
                "body": {
                    "livenessDecision": "realface",
                    "target": {
                        "faceRectangle": {
                            "top": 59,
                            "left": 121,
                            "width": 409,
                            "height": 395
                        },
                        "fileName": "content.bin",
                        "timeOffsetWithinFile": 0,
                        "imageType": "Color"
                    },
                    "modelVersionUsed": "2022-10-15-preview.04",
                    "verifyResult": {
                        "matchConfidence": 0.9304124,
                        "isIdentical": true
                    }
                },
                "statusCode": 200,
                "latencyInMilliseconds": 1306
            },
            "digest": "2B39F2E0EFDFDBFB9B079908498A583545EBED38D8ACA800FF0B8E770799F3BF"
        },
        "id": "3847ffd3-4657-4e6c-870c-8e20de52f567",
        "createdDateTime": "2023-10-31T16:58:19.8942961+00:00",
        "authTokenTimeToLiveInSeconds": 600,
        "deviceCorrelationId": "723d6d03-ef33-40a8-9682-23a1feb7bccd",
        "sessionExpired": true
    }
    
  3. 더 이상 결과를 쿼리하지 않으면 앱 서버가 세션을 삭제할 수 있습니다.

    await sessionClient.DeleteLivenessWithVerifySessionAsync(sessionId);
    Console.WriteLine($"The session {sessionId} is deleted.");
    

리소스 정리

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

다음 단계

활성 API의 다른 옵션에 대해 알아보려면 Azure AI 비전 SDK 참조를 확인합니다.

활성 솔루션을 오케스트레이션하는 데 사용할 수 있는 기능에 대해 자세히 알아보려면 세션 REST API 참조를 확인합니다.