Руководство: как обнаружить живость на лицах

Узнайте, как интегрировать обнаружение активности лиц в рабочий процесс с помощью логики на стороне сервера и клиентских приложений внешнего интерфейса.

Подсказка

Общие сведения об обнаружении живости лица см. в концептуальном руководстве.

В этом руководстве описано, как запустить интерфейсное приложение с сервером приложений для обнаружения активности. Кроме того, можно добавить проверку лиц на различных платформах и языках.

Это важно

Пакеты SDK для клиента распознавания лиц для определения живости — это функция с ограниченным доступом. Необходимо запросить доступ к функции проверки живости, заполнив форму-заявку на распознавание лиц. Когда подписка Azure предоставляет доступ, вы можете скачать пакет SDK для распознавания лиц.

Необходимые условия

  • Подписка Azure — создайте бесплатную учетную запись.
  • Для вашей учетной записи Azure должна быть назначена роль Участник служб когнитивных служб, чтобы вы могли согласиться с условиями ответственного использования ИИ и создать ресурс. Чтобы назначить эту роль своей учетной записи, следуйте инструкциям, описанным в документации по назначению ролей, или обратитесь к администратору.
  • После получения подписки Azure на портале Azure, чтобы получить ключ и конечную точку. После развертывания выберите Перейти к ресурсу.
    • Вам потребуется ключ и конечная точка из ресурса, создаваемого для подключения приложения к службе распознавания лиц.
  • Доступ к закрытым артефактам, необходимым для Azure Vision в пакете инструментов Foundry, при использовании клиентского SDK для распознавания лиц на мобильных устройствах (iOS и Android) и в Интернет.
  • Знакомство с функцией определения живости лица. См. концептуальное руководство.

Подсказка

После выполнения необходимых условий вы можете попробовать опыт взаимодействия в реальном времени на следующих платформах:

  • iOS: iOS App Store — коснитесь экрана приложения 10 раз после установки, чтобы включить режим разработчика.
  • Android: Google Play Store — коснитесь экрана приложения 10 раз после установки, чтобы включить режим разработчика.
  • Веб: испытайте его прямо в Vision Studio.

Вы также можете создать и запустить полный пример внешнего интерфейса (iOS, Android или Web) из раздела "Примеры ".

Подготовка интерфейсного приложения

Пакеты SDK доступны на нескольких языках, чтобы упростить интеграцию с интерфейсным приложением. Ознакомьтесь с readME для выбранного пакета SDK в следующих разделах, чтобы интегрировать пользовательский интерфейс и обязательный код.

Это важно

Для каждого внешнего пакета SDK требуется доступ к закрытому ресурсу для успешной компиляции. См. следующие инструкции по настройке этого доступа.

Для Swift iOS:

Для Kotlin/Java Android:

Для JavaScript Web:

После интеграции с фронтенд-приложением пакет SDK запускает камеру, направляет пользователя для настройки своей позиции, создает пакет данных активности и отправляет его в службу Azure Face для обработки.

Отслеживайте раздел Releases для новых обновлений версии пакета SDK и включите оповещения об автоматическом обновлении зависимостей, такие как GitHub Dependabot (для репозиториев GitHub) или Ремонт (GitHub, GitLab, Bitbucket, Azure Repos).

Обнаружение живости

Ниже описан процесс оркестрации активности.

Схема рабочего процесса проверки живости в Azure Face.

  1. Интерфейсное приложение запускает проверку активности и уведомляет сервер приложений.

  2. Сервер приложений создает новый сеанс активности с помощью Службы распознавания лиц Azure. Служба создает сеанс активности и отвечает маркером авторизации сеанса. Дополнительные сведения о каждом параметре запроса, связанном с созданием сеанса liveness, см. в разделе операция 'Создание сеанса liveness'.

    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.

    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}");
    

Обнаружение живости с верификацией лица

Объединение проверки лица с определением реальности позволяет осуществлять биометрическую проверку конкретного человека, представляющего интерес, с дополнительной гарантией того, что этот человек физически присутствует в системе.

Схема рабочего процесса liveness-with-face-authentication в Azure Face.

Интеграция обнаружения активности с проверкой включает две части:

Шаг 1. Выбор эталонного изображения

Чтобы получить наиболее точные результаты распознавания, следуйте рекомендациям, приведенным в требованиях к композиции для сценариев проверки идентификаторов.

Шаг 2. Настройка оркестрации живости с проверкой

На следующих высокоуровневых шагах показано, как оркестрировать живость с проверкой.

  1. Предоставьте эталонный образ проверки с помощью одного из следующих двух методов:

    • Сервер приложений предоставляет эталонный образ при создании сеанса проверки живости. Дополнительные сведения о каждом параметре запроса, связанном с созданием сеанса активности с проверкой подлинности, см. в статье Liveness With Verify Create Session Operation.

      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. Извлеките sessionImageId из шага сеанса Get-Result.
  3. Скачайте изображение сеанса (упомянутое в API операции получения изображения сеанса Liveness), или предоставьте sessionImageId в операции API обнаружения по идентификатору изображения сеанса, чтобы продолжить другие операции анализа лиц или операций с идентичностью лиц. Дополнительные сведения об этих операциях см. в концепциях обнаружения лиц и концепциях распознавания лиц.

Варианты поддержки

Помимо использования основных вариантов поддержки средств Foundry, вы также можете опубликовать свои вопросы в разделе вопросов репозитория SDK.

Чтобы узнать, как интегрировать решение liveness в существующее приложение, ознакомьтесь со справочником по пакету SDK для визуального распознавания Azure.

Чтобы узнать больше о функциях, доступных для оркестрации решения для проверки живости, смотрите справочник по сеансовому REST API.