共用方式為


教學課程:偵測臉部活動

學習如何利用伺服器端邏輯及伴隨前端客戶端應用程式,將臉部直播偵測整合進您的工作流程中。

小提示

如需臉部活躍度偵測的一般資訊,請參閱 概念指南

在這個教學中,你將學習如何搭配應用程式伺服器執行前端應用程式來進行活度偵測。 你也可以在各種平台和語言上新增 臉部驗證 功能。

重要

適用於臉部活動的臉部用戶端 SDK 是一項受管制功能。 您必須填寫臉部辨識資訊表單以要求存取活體檢測功能。 當您的 Azure 訂用帳戶獲得存取權時,您可以下載人臉活體檢測 SDK。

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • 你的 Azure 帳號必須被指派一個 認知服務貢獻 者角色,這樣你才能同意負責的 AI 條款並建立資源。 若要將此角色指派給您的帳戶,請遵循指派角色文件中的步驟,或連絡系統管理員。
  • 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立臉部資源,以取得您的金鑰和端點。 在其部署後,選取 [前往資源]
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至人臉服務。
  • 存取適用於行動裝置 (iOS 和 Android)和 Web 的 Foundry Tools 臉部用戶端 SDK 中 Azure Vision 所需的閘道成品。
  • 熟悉臉部活動偵測功能。 請參閱 概念指南

小提示

完成先決條件後,即可在以下平台上嘗試活動體驗:

  • iOS: iOS App Store — 安裝後點擊應用程式畫面 10 次即可啟用開發者模式。
  • Android: Google Play 商店 — 安裝後點擊應用程式畫面 10 次即可啟用開發者模式。
  • 網路:直接在 Vision Studio 裡試試看。

你也可以從 範例 區塊建立並執行完整的前端範例(iOS、Android 或網頁版)。

準備前端應用程式

我們提供多種語言的 SDK,以簡化與您的前端應用程式的整合。 請參考您所選 SDK 的 README 中以下章節,以整合使用者介面及所需的程式碼。

重要

每個前端 SDK 都需要存取閘控資產才能成功編譯。 請參考以下說明來設定此存取權限。

針對 Swift iOS:

對於 Kotlin/Java Android:

針對 JavaScript Web:

一旦整合進前端應用程式,SDK 會啟動攝影機,引導使用者調整位置,撰寫直播負載,並傳送至 Azure AI Face 服務進行處理。

請監控倉庫的 Releases 區 塊,隨時更新新的 SDK 版本,並啟用自動相依性更新警示——例如 GitHub Dependabot(針對 GitHub 倉庫)或 Renovate(針對 GitHub、GitLab、Bitbucket、Azure Repos)。

執行臉部活動偵測

以下步驟說明活躍度的協調流程:

Azure AI 臉部中臉部活動工作流程的圖表。

  1. 前端應用程式會啟動存活檢查,並通知應用程式伺服器。

  2. 應用程式伺服器會使用 Azure AI 臉部服務建立新的臉部活動工作階段。 該服務建立一個活躍度工作階段,並回傳工作階段授權權杖。 關於建立 liveness session 所涉及的每個請求參數的更多資訊,請參閱 Liveness Create Session 操作

    var endpoint = new Uri(System.Environment.GetEnvironmentVariable("FACE_ENDPOINT"));
    var key = new AzureKeyCredential(System.Environment.GetEnvironmentVariable("FACE_APIKEY"));
    
    var body = JsonSerializer.Serialize(new
    {
        livenessOperationMode = "PassiveActive",
        deviceCorrelationId = "723d6d03-ef33-40a8-9682-23a1feb7bccd",
        enableSessionImage = true
    });
    
    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key);
    
    var response = await client.PostAsync(
        $"{endpoint}/face/v1.2/detectLiveness-sessions",
        new StringContent(body, Encoding.UTF8, "application/json"));
    
    response.EnsureSuccessStatusCode();
    
    using var doc  = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
    var root       = doc.RootElement;
    
    Console.WriteLine("Session created");
    Console.WriteLine($"sessionId : {root.GetProperty("sessionId").GetString()}");
    Console.WriteLine($"authToken : {root.GetProperty("authToken").GetString()}");
    

    回應主體的範例:

    {
        "sessionId": "a6e7193e-b638-42e9-903f-eaf60d2b40a5",
        "authToken": "<session-authorization-token>",
        "status": "NotStarted",
        "modelVersion": "2025-05-20",
        "results": {
            "attempts": []
        }
    }
    
  3. 應用伺服器會將會話授權權杖回傳給前端應用程式。

  4. 前端應用程式會使用工作階段授權權杖來啟動臉部活躍度偵測器,進而啟動活躍度流程。

        FaceLivenessDetector(
            sessionAuthorizationToken = FaceSessionToken.sessionToken,
            verifyImageFileContent = FaceSessionToken.sessionSetInClientVerifyImage,
            deviceCorrelationId = "null",
            onSuccess = viewModel::onSuccess,
            onError = viewModel::onError
        )
    
  5. SDK 會啟動相機、引導使用者正確定位,然後準備承載以呼叫即時偵測服務端點。

  6. SDK 呼叫 Azure Vision Face 服務來執行活度偵測。 服務回應後,SDK 會通知前端應用程式活體檢查完成。 附註:服務回應不包含活躍度決策。 你需要向應用程式伺服器查詢這些資訊。

  7. 前端應用程式會將存活檢查的完成狀態傳送到應用程式伺服器。

  8. 應用程式伺服器會查詢 Azure Vision Face 服務的活體偵測結果。

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key);
    
    var response = await client.GetAsync(
        $"{endpoint}/face/v1.2/livenessSessions/{sessionId}/result");
    
    response.EnsureSuccessStatusCode();
    
    using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
    var root = doc.RootElement;
    var attempts = root.GetProperty("results").GetProperty("attempts");
    var latestAttempt = attempts[attempts.GetArrayLength() - 1];
    var attemptStatus = latestAttempt.GetProperty("attemptStatus").GetString();
    
    Console.WriteLine($"Session id: {root.GetProperty("sessionId").GetString()}");
    Console.WriteLine($"Session status: {root.GetProperty("status").GetString()}");
    Console.WriteLine($"Latest attempt status: {attemptStatus}");
    
    if (attemptStatus == "Succeeded")
        Console.WriteLine($"Liveness detection decision: {latestAttempt.GetProperty("result").GetProperty("livenessDecision").GetString()}");
    else
    {
        var error = latestAttempt.GetProperty("error");
        Console.WriteLine($"Error: {error.GetProperty("code").GetString()} - {error.GetProperty("message").GetString()}");
    }
    

    回應主體的範例:

    {
        "sessionId": "b12e033e-bda7-4b83-a211-e721c661f30e",
        "authToken": "eyJhbGciOiJFUzI1NiIsIm",
        "status": "NotStarted",
        "modelVersion": "2024-11-15",
        "results": {
            "attempts": [
                {
                    "attemptId": 2,
                    "attemptStatus": "Succeeded",
                    "result": {
                    "livenessDecision": "realface",
                    "targets": {
                        "color": {
                        "faceRectangle": {
                                "top": 669,
                                "left": 203,
                                "width": 646,
                                "height": 724
                            }
                        }
                    },
                    "digest": "B0A803BB7B26F3C8F29CD36030F8E63ED3FAF955FEEF8E01C88AB8FD89CCF761",
                    "sessionImageId": "Ae3PVWlXAmVAnXgkAFt1QSjGUWONKzWiSr2iPh9p9G4I"
                    }
                },
                {
                    "attemptId": 1,
                    "attemptStatus": "Failed",
                    "error": {
                    "code": "FaceWithMaskDetected",
                    "message": "Mask detected on face image.",
                    "targets": {
                            "color": {
                            "faceRectangle": {
                                "top": 669,
                                "left": 203,
                                "width": 646,
                                "height": 724
                            }
                            }
                        }
                    }
                }
            ]
        }
    }
    
  9. 應用程式伺服器在查詢所有會話結果後會刪除該會話。

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key);
    
    await client.DeleteAsync($"{endpoint}/face/v1.2/livenessSessions/{sessionId}");
    Console.WriteLine($"Session deleted: {sessionId}");
    

搭配臉部驗證執行臉部活動偵測

將臉部驗證與臉部活動偵測結合,可讓特定感興趣的人員進行生物特徵辨識驗證,並保證該人員實際存在於系統中。

Azure AI Face 活體檢測與驗證工作流程的圖表。

將活體偵測與驗證整合包含兩個部分:

步驟 1 - 選取參考影像

為了獲得最準確的辨識結果,請遵循身分 驗證情境寫作要求中列出的建議。

步驟 2 - 設定含驗證的活躍度的協調流程

以下高階步驟會顯示如何協調含驗證的活躍度:

  1. 請使用以下兩種方法之一提供驗證參考影像:

    • 應用程式伺服器會在建立臉部活動工作階段時提供參考影像。 關於建立帶驗證的生命狀態會話所需的每個請求參數的更多資訊,請參見 「生命狀態驗證建立會話操作」。

      var endpoint = new Uri(System.Environment.GetEnvironmentVariable("FACE_ENDPOINT"));
      var key      = System.Environment.GetEnvironmentVariable("FACE_APIKEY");
      
      // Create the JSON part
      var jsonPart = new StringContent(
          JsonSerializer.Serialize(new
          {
              livenessOperationMode = "PassiveActive",
              deviceCorrelationId = "723d6d03-ef33-40a8-9682-23a1feb7bcc",
              enableSessionImage = true
          }),
          Encoding.UTF8,
          "application/json"
      );
      jsonPart.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
      {
          Name = "CreateLivenessWithVerifySessionRequest"
      };
      
      // Create the file part
      using var fileStream = File.OpenRead("test.png");
      var filePart = new StreamContent(fileStream);
      filePart.Headers.ContentType = new MediaTypeHeaderValue("image/png");
      filePart.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
      {
          Name = "VerifyImage",
          FileName = "test.png"
      };
      
      // Build multipart form data
      using var formData = new MultipartFormDataContent();
      formData.Add(jsonPart);
      formData.Add(filePart);
      
      using var client = new HttpClient();
      client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key);
      
      var response = await client.PostAsync($"{endpoint}/face/v1.2/createLivenessWithVerifySession", formData);
      response.EnsureSuccessStatusCode();
      
      using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
      var root = doc.RootElement;
      
      Console.WriteLine("Session created.");
      Console.WriteLine($"Session id: {root.GetProperty("sessionId").GetString()}");
      Console.WriteLine($"Auth token: {root.GetProperty("authToken").GetString()}");
      

      回應主體的範例:

      {
          "sessionId": "3847ffd3-4657-4e6c-870c-8e20de52f567",
          "authToken": "<session-authorization-token>",
          "status": "NotStarted",
          "modelVersion": "2024-11-15",
          "results": {
              "attempts": [],
              "verifyReferences": [
              {
                  "referenceType": "image",
                  "faceRectangle": {
                  "top": 98,
                  "left": 131,
                  "width": 233,
                  "height": 300
                  },
                  "qualityForRecognition": "high"
              }
              ]
          }
      }
      
    • 前端應用程式會在初始化行動SDK時提供參考映像。 這個情境在網頁解決方案中並不支援。

          FaceLivenessDetector(
              sessionAuthorizationToken = FaceSessionToken.sessionToken,
              verifyImageFileContent = FaceSessionToken.sessionSetInClientVerifyImage,
              deviceCorrelationId = "null",
              onSuccess = viewModel::onSuccess,
              onError = viewModel::onError
          )
      
  2. 應用程式伺服器現在除了臉部活動結果之外,也可以查詢驗證結果。

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key);
    
    var response = await client.GetAsync($"{endpoint}/face/v1.2/livenessSessions/{sessionId}/result");
    response.EnsureSuccessStatusCode();
    
    using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
    var root = doc.RootElement;
    
    var attempts = root.GetProperty("results").GetProperty("attempts");
    var latestAttempt = attempts[attempts.GetArrayLength() - 1];
    var attemptStatus = latestAttempt.GetProperty("attemptStatus").GetString();
    
    Console.WriteLine($"Session id: {root.GetProperty("sessionId").GetString()}");
    Console.WriteLine($"Session status: {root.GetProperty("status").GetString()}");
    Console.WriteLine($"Latest attempt status: {attemptStatus}");
    
    if (attemptStatus == "Succeeded")
    {
        var decision = latestAttempt.GetProperty("result").GetProperty("livenessDecision").GetString();
        var verify   = latestAttempt.GetProperty("verifyResult");
        Console.WriteLine($"Liveness detection decision: {decision}");
        Console.WriteLine($"Verify isIdentical: {verify.GetProperty("isIdentical").GetBoolean()}");
        Console.WriteLine($"Verify matchConfidence: {verify.GetProperty("matchConfidence").GetDouble()}");
    }
    else
    {
        var err = latestAttempt.GetProperty("error");
        Console.WriteLine($"Error: {err.GetProperty("code").GetString()} - {err.GetProperty("message").GetString()}");
    }
    

    回應主體的範例:

    {
        "sessionId": "b12e033e-bda7-4b83-a211-e721c661f30e",
        "authToken": "eyJhbGciOiJFUzI1NiIsIm",
        "status": "NotStarted",
        "modelVersion": "2024-11-15",
        "results": {
            "attempts": [
            {
                "attemptId": 2,
                "attemptStatus": "Succeeded",
                "result": {
                "livenessDecision": "realface",
                "targets": {
                    "color": {
                    "faceRectangle": {
                        "top": 669,
                        "left": 203,
                        "width": 646,
                        "height": 724
                    }
                    }
                },
                "verifyResult": {
                    "matchConfidence": 0.08871888,
                    "isIdentical": false
                },
                "digest": "B0A803BB7B26F3C8F29CD36030F8E63ED3FAF955FEEF8E01C88AB8FD89CCF761",
                "sessionImageId": "Ae3PVWlXAmVAnXgkAFt1QSjGUWONKzWiSr2iPh9p9G4I",
                "verifyImageHash": "43B7D8E8769533C3290DBD37A84D821B2C28CB4381DF9C6784DBC4AAF7E45018"
                }
            },
            {
                "attemptId": 1,
                "attemptStatus": "Failed",
                "error": {
                    "code": "FaceWithMaskDetected",
                    "message": "Mask detected on face image.",
                    "targets": {
                        "color": {
                        "faceRectangle": {
                                "top": 669,
                                "left": 203,
                                "width": 646,
                                "height": 724
                            }
                        }
                    }
                }
            }
            ],
            "verifyReferences": [
                {
                    "referenceType": "image",
                    "faceRectangle": {
                    "top": 316,
                    "left": 131,
                    "width": 498,
                    "height": 677
                    },
                    "qualityForRecognition": "high"
                }
            ]
            }
        }
    
  3. 如果您不再需要會話的結果,應用程式伺服器可以刪除會話。

    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key);
    
    await client.DeleteAsync($"{endpoint}/face/v1.2/livenessWithVerifySessions/{sessionId}");
    Console.WriteLine($"Liveness-with-Verify session deleted: {sessionId}");
    

在臉部活動偵測之後執行其他臉部作業

可選擇性地,在活體檢查後還能執行額外的人臉操作,例如人臉分析(取得人臉屬性)和人臉身份操作。

  1. enableSessionImage中將參數設定true
  2. Session-Get-Result 步驟中擷取 sessionImageId
  3. 下載會話影像(參考 Liveness Get Session Image Operation API 中),或在sessionImageId」操作中提供,以繼續進行其他臉部分析或臉部身份操作。 如需這些作業的詳細資訊,請參閱 臉部偵測概念臉部辨識概念

支援選項

除了使用 Foundry Tools 的主要支援選項外,你也可以在 SDK 倉庫的 issues 區塊發問。

想了解如何將活化解決方案整合到現有應用程式中,請參閱 Azure Vision SDK 參考資料。

若要深入了解可用來協調臉部活動解決方案的功能,請參閱工作階段 REST API 參考。