チュートリアル: 顔のライブネスを検出する

顔のライブネス検出は、入力ビデオ ストリーム内の顔がリアル (ライブ) かフェイク (スプーフィング) かを判断するために使用されます。 これは、写真、ビデオ、マスク、または他人になりすますその他の手法を使ってシステムにアクセスしようとする企てを防ぐための、生体認証システムにおける重要な構成要素です。

ライブネス検出の目的は、認証時にシステムが物理的に存在するライブユーザーと対話していることを確認することです。 このようなシステムは、デジタル ファイナンス、リモート アクセスの制御、オンライン本人確認プロセスの増加に伴ってますます重要になっています。

Azure AI Face ライブネス検出ソリューションは、紙のプリントアウト、2D/3D マスク、スマートフォンやラップトップ上のスプーフィング プレゼンテーションなど、さまざまな種類のスプーフィングから正常に保護します。 ライブネス検出は、現在も活発に研究されている分野であり、ますます高度になっているスプーフィング攻撃に対抗するために継続的に改善されています。 ソリューション全体が新しい種類の攻撃に対してより堅牢になるにつれて、継続的な改善がクライアントとサービス コンポーネントにロールアウトされます。

重要

ライブネス用の Face クライアント SDK は、ゲートされたフィーチャーです。 顔認識の取り込みフォームにを入力して、ライブネスフィーチャーへのアクセスを要求する必要があります。 Azure サブスクリプションにアクセス権が付与されたら、Face ライブネスSDK をダウンロードできます。

はじめに

ライブネス ソリューションの統合には、フロントエンド モバイル/Web アプリケーションとアプリ サーバー/オーケストレーターという 2 つの異なるコンポーネントが含まれます。

Azure AI Face のライブネス ワークフローの図。

  • フロントエンド アプリケーション: フロントエンド アプリケーションは、アプリ サーバーから認可を受けて、ライブネス検出を開始します。 その主要な目的は、カメラをアクティブにして、ライブネス検出プロセスを通じてエンド ユーザーを正確にガイドすることです。
  • アプリ サーバー: アプリ サーバーは、ライブネス検出セッションを作成し、特定のセッションについて Face サービスから認可トークンを取得するためのバックエンド サーバーとして機能します。 このトークンにより、フロントエンド アプリケーションによるライブネス検出の実行が認可されます。 アプリ サーバーの目的は、セッションを管理し、フロントエンド アプリケーションの認可を付与し、ライブネス検出プロセスの結果を表示することです。

さらに、顔認証とライブネス検出を組み合わせて、その人物が指定された特定の人物であるかどうかを検証します。 次の表は、ライブネス検出機能の詳細を説明したものです。

機能 説明
ライブネス検出 入力が本物か偽物かを判断します。ライブネス チェックを開始してその結果を照会する権限を持っているのは、アプリ サーバーのみです。
顔認証によるライブネス検出 入力が本物か偽物かを判断し、指定した参照画像に基づいて人物の身元を確認します。 アプリ サーバーまたはフロントエンド アプリケーションのいずれかが参照画像を指定できます。 ライブネス チェックを開始してその結果を照会する権限を持っているのは、アプリ サーバーのみです。

このチュートリアルでは、さまざまな言語 SDK を使って、フロントエンド アプリケーションとアプリ サーバーを運用してライブネス検出顔認証によるライブネス検出を実行する方法について説明します。

前提条件

  • Azure サブスクリプション - 無料アカウントを作成します
  • 責任ある AI 用語に同意してリソースを作成するには、Azure アカウントに Cognitive Services 共同作成者 ロールが割り当てられている必要があります。 このロールをアカウントに割り当てるには、ロールの割り当てに関するドキュメントの手順に従うか、管理者にお問い合わせください。
  • Azure サブスクリプションを入手したら、Azure portal で Face リソースを作成し、キーとエンドポイントを取得します。 デプロイされたら、 [リソースに移動] を選択します。
    • アプリケーションを Face サービスに接続するには、作成したリソースのキーとエンドポイントが必要です。
    • Free 価格レベル (F0) を使用してサービスを試用し、後から運用環境用の有料レベルにアップグレードすることができます。
  • モバイル用 (IOS、Android) および Web 用 Azure AI Vision Face Client SDK へのアクセス。 開始するには、SDK にアクセスするために 顔認識 の制限付きアクセスフィーチャー を申請する必要があります。 詳細については、「 Face Limited Access 」ページを参照してください。

ライブネス検出を実行するようにフロントエンド アプリケーションとアプリ サーバーをセットアップする

フロントエンド アプリケーションとアプリ サーバー用の SDK は、さまざまな言語で提供されています。 以下の手順を参照して、ご自身のフロントエンド アプリケーションとアプリ サーバーをセットアップしてください。

フロントエンド アプリケーション用の SDK をダウンロードする

SDK にアクセスしたら、azure-ai-vision-sdk GitHub リポジトリの指示に従って、UI とコードをネイティブ モバイル アプリケーションに統合します。 ライブネス SDK では、Android モバイル アプリケーションの場合は Java/Kotlin、iOS モバイル アプリケーションの場合は Swift、Web アプリケーションの場合は JavaScript がサポートされています。

アプリケーションにコードを追加すると、SDK はカメラの起動を処理し、エンドユーザーに位置を調整するよう誘導し、ライブネス ペイロードを作成し、Azure AI Face クラウド サービスを呼び出してライブネス ペイロードを処理します。

アプリ サーバー用の Azure AI Face クライアント ライブラリをダウンロードする

アプリ サーバー/オーケストレーターは、ライブネス セッションのライフサイクルを制御する役割を果たします。 アプリ サーバーは、ライブネス チェックを実行する前にセッションを作成する必要があります。ライブネス チェックが完了したら、その結果を照会し、セッションを削除できます。 アプリ サーバーを簡単に実装できるように、さまざまな言語でライブラリが用意されています。 次の手順に従って、必要なパッケージをインストールします。

環境変数を作成する

この例では、アプリケーションを実行しているローカル コンピューター上の環境変数に資格情報を書き込みます。

Azure portal に移動します。 「前提条件」 セクションで作成したリソースが正常にデプロイされた場合、[次の手順] の下にある [リソースに移動] を選択します。 キーとエンドポイントは、[キーとエンドポイント] ページの [リソース管理] にあります。 リソース キーは Azure サブスクリプション ID と同じではありません。

キーとエンドポイントの環境変数を設定するには、コンソール ウィンドウを開き、オペレーティング システムと開発環境の指示に従います。

  • FACE_APIKEY 環境変数を設定するには、<your_key> をリソースのキーの 1 つに置き換えます。
  • FACE_ENDPOINT 環境変数を設定するには、<your_endpoint> をリソースのエンドポイントに置き換えます。

重要

API キーを使用する場合は、それを Azure Key Vault などの別の場所に安全に保存します。 API キーは、コード内に直接含めないようにし、絶対に公開しないでください。

AI サービスのセキュリティの詳細については、「Azure AI サービスに対する要求の認証」を参照してください。

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. アプリ サーバーは、フロントエンド アプリケーションに session-authorization-token を返します。

  4. フロントエンド アプリケーションは、Azure AI Vision SDK の初期化時に session-authorization-token を提示します。

    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 Vision Face サービスを呼び出して、ライブネス検出を実行します。 サービスが応答すると、SDK は、ライブネス チェックが完了したことをフロントエンド アプリケーションに通知します。

  7. フロントエンド アプリケーションは、ライブネス チェックの完了をアプリ サーバーに中継します。

  8. アプリ サーバーは、Azure AI Vision 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.");
    

顔検証を使用してライブネス検出を実行する

顔検証とライブネス検出を組み合わせることで、特定の関心のあるユーザーの生体認証検証が可能になり、ユーザーがシステムに物理的に存在することが保証されます。 ライブネスと検証の統合には、次の 2 つの部分があります:

  1. 適切な参照イメージを選択します。
  2. 検証を使用して、ライブネスのオーケストレーションを設定します。

Azure AI Face の顔認証によるライブネス ワークフローの図。

参照イメージを選択する

次のヒントを使用して、入力画像が最も正確な認識結果を得られるようにします。

技術的な要件

  • サポートされている入力画像形式は、JPEG、PNG、GIF (最初のフレーム)、BMP です。
  • 画像ファイル サイズは 6 MB 以内であることが必要です。
  • 画像が顔認識を試行するのに十分な品質である可能性が高いかどうかを示す一般的なガイドラインとして、適用可能な検出モデルを使用する場合は、 qualityForRecognition 属性がある 顔検出 操作を利用できます。 "high" 品質イメージのみが、個人の登録で、"medium"以上の品質が 識別シナリオに推奨されます。

構成要件

  • 写真は鮮明で鮮明で、ぼやけていない、ピクセル化された、歪んでいる、または損傷している。
  • 顔の傷や顔の外観を取り除くために写真は変更されません。
  • 写真は RGB カラーでサポートされている形式 (JPEG、PNG、WEBP、BMP) である必要があります。 推奨される顔サイズは 200 ピクセル x 200 ピクセルです。 顔のサイズが 200 ピクセル x 200 ピクセルを超える場合、AI 品質は向上せず、サイズは 6 MB 以下になります。
  • ユーザーは、眼鏡、マスク、帽子、ヘッドフォン、ヘッドカバー、またはフェイスカバーを着用していません。 顔は障害物を含まない必要があります。
  • あなたの顔を隠さない限り、顔の宝石類は許可されています。
  • 写真に表示する顔は 1 つだけです。
  • 顔は、両目を開き、口を閉じ、極端な表情や頭の傾きをしてない、中立的な正面向きのポーズである必要があります。
  • 顔は影や赤目を含まない必要があります。 これらのいずれかが発生した場合は、写真を再撮影してください。
  • 背景は均一でプレーンで、影を含まない必要があります。
  • 顔はイメージ内の中央に配置し、画像の少なくとも 50% を塗りつぶしている必要があります。

検証を使用して、ライブネスのオーケストレーションを設定します。

検証オーケストレーションでのライブネスに関連する大まかなステップを次に示します:

  1. 次の 2 つの方法のいずれかを使って、検証の参照画像を提供します。

    • アプリ サーバーは、ライブネス セッションの作成時に参照イメージを提供します。 検証を伴うライブネス セッションの作成に関連する各要求パラメーターの詳細については、検証を伴うライブネス セッションの作成操作に関する情報を参照してください。

      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 の初期化時に参照画像を提供します。 このシナリオは、Web ソリューションではサポートされていません。

      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 Vision SDK リファレンスを参照してください。

ライブネス ソリューションのオーケストレーションを行うために使用できる機能について詳しくは、Session REST API リファレンスを参照してください。