Share via


使用 PersonDirectory 資料結構 (預覽版)

警告

臉部辨識服務存取受限於資格和使用準則,以支援我們的「負責任的 AI 原則」。 臉部辨識服務僅供 Microsoft 受管理的客戶和合作夥伴使用。 請使用臉部辨識受理表單以申請存取。 如需詳細資訊,請參閱臉部的有限存取權頁面。

若要執行臉部辨識作業 (例如識別和尋找類似的項目),臉部 API 客戶必須建立各種人員物件清單。 PersonDirectory 是公開預覽中的一種資料結構,其中包含新增至目錄之每個 Person 身分識別的唯一識別碼、選擇性的名稱字串和選擇性的使用者中繼資料字串。 請遵循本指南,了解如何使用 PersonDirectory 進行基本工作。

PersonDirectory 的優點

目前,臉部 API 提供的 LargePersonGroup 結構具有類似的功能,但受限於 1 百萬個身分識別。 PersonDirectory 結構最多可擴大至 7 千 5 百萬個身分識別。

PersonDirectory 和先前的資料結構的主要差別在於,在向人員物件新增臉部後,您就不再需要進行任何定型 API 呼叫,更新程序會自動發生。

Prerequisites

  • Azure 訂用帳戶 - 建立免費帳戶
  • 擁有 Azure 訂用帳戶之後,在 Azure 入口網站中建立臉部資源,以取得您的金鑰和端點。 在其部署後,選取 [前往資源]。
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至 Face API。 您將在下列程式碼中貼上您的金鑰和端點。
    • 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於生產環境。

將人員新增至 PersonDirectory

人員PersonDirectory 中的基本註冊單位。 將人員新增至目錄之後,您可以為該人員新增多達 248 個臉部影像 (每一辨識模型)。 然後,您可以使用不同的範圍識別這些影像中的臉部。

建立人員

若要建立人員,您必須呼叫 CreatePerson API,並提供名稱或 userData 屬性值。

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

var addPersonUri = "https:// {endpoint}/face/v1.0-preview/persons";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("name", "Example Person");
body.Add("userData", "User defined data");
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PostAsync(addPersonUri, content); 
}

CreatePerson 呼叫會傳回為人員和作業位置產生的識別碼。 人員資料將以非同步方式處理,因此您可以使用作業位置來擷取結果。

等候非同步作業完成

您必須使用傳回的作業位置字串查詢非同步作業狀態,以檢查作業進度。

首先,您應該定義如下的資料模型來處理狀態回應。

[Serializable]
public class AsyncStatus
{
    [DataMember(Name = "status")]
    public string Status { get; set; }

    [DataMember(Name = "createdTime")]
    public DateTime CreatedTime { get; set; }

    [DataMember(Name = "lastActionTime")]
    public DateTime? LastActionTime { get; set; }

    [DataMember(Name = "finishedTime", EmitDefaultValue = false)]
    public DateTime? FinishedTime { get; set; }

    [DataMember(Name = "resourceLocation", EmitDefaultValue = false)]
    public string ResourceLocation { get; set; }

    [DataMember(Name = "message", EmitDefaultValue = false)]
    public string Message { get; set; }
}

使用上述 HttpResponseMessage,您即可輪詢 URL 並等候結果。

string operationLocation = response.Headers.GetValues("Operation-Location").FirstOrDefault();

Stopwatch s = Stopwatch.StartNew();
string status = "notstarted";
do
{
    if (status == "succeeded")
    {
        await Task.Delay(500);
    }

    var operationResponseMessage = await client.GetAsync(operationLocation);

    var asyncOperationObj = JsonConvert.DeserializeObject<AsyncStatus>(await operationResponseMessage.Content.ReadAsStringAsync());
    status = asyncOperationObj.Status;

} while ((status == "running" || status == "notstarted") && s.Elapsed < TimeSpan.FromSeconds(30));

傳回的狀態為「成功」,則會將人員物件視為已新增至目錄。

注意

來自建立人員呼叫的非同步作業不需要顯示「成功」狀態,即可將臉部新增至其中,但必須先完成作業,才能將人員新增至 DynamicPersonGroup (請參閱下方的建立和更新 DynamicPersonGroup),或是在識別呼叫期間進行比較。 確認呼叫可在臉部成功新增至人員之後立即運作。

將臉部新增至人員

在您透過「建立人員」呼叫取得人員識別碼後,即可為每個辨識模型的人員新增最多 248 個臉部影像。 指定要在呼叫中使用的辨識模型 (並選擇性地指定偵測模型),因為每個辨識模型下的資料將會在 PersonDirectory 內個別處理。

目前支援的辨識模型為:

  • Recognition_02
  • Recognition_03
  • Recognition_04

此外,如果影像包含多個臉部,您必須為作為預定目標的臉部指定矩形週框方塊。 下列程式碼會將臉部新增至人員物件。

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

// Optional query strings for more fine grained face control
var queryString = "userData={userDefinedData}&targetFace={left,top,width,height}&detectionModel={detectionModel}";
var uri = "https://{endpoint}/face/v1.0-preview/persons/{personId}/recognitionModels/{recognitionModel}/persistedFaces?" + queryString;

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("url", "{image url}");
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PostAsync(uri, content);
}

在「新增臉部呼叫」之後,臉部資料將會以非同步方式處理,而您必須以和之前相同的方式等候作業成功。

當新增臉部的作業完成時,資料會在識別呼叫中準備就緒。

建立和更新 DynamicPersonGroup

DynamicPersonGroupsPersonDirectory人員物件的參考集合,可用來建立目錄子集。 常見用法之一,是您想要在識別作業中取得較少的誤判為真和較高的精確度,而將範圍限定為您預期要符合的人員物件。 實際的使用案例包括在較大的校園或組織間存取特定建築物的目錄。 組織目錄可能包含 500 萬個人,但您只需要搜尋特定的 800 個人以找出特定建築物,因此您將建立包含這些特定人員的 DynamicPersonGroup

如果您先前使用過 PersonGroup,請留意兩項主要的差異:

  • DynamicPersonGroup 內的每個都是 PersonDirectory 中實際人員的參考,這表示不需要在每個群組中重新建立人員
  • 如前幾節所述,不需要進行定型呼叫,因為臉部資料會自動在目錄層級進行處理。

建立群組

若要建立 DynamicPersonGroup,您必須提供包含英數字元或虛線字元的群組識別碼。 此識別碼將作為群組各種用途的唯一識別碼。

有兩種方式可以初始化群組集合。 您可以先建立空的群組,稍後再加以填入:

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

var uri = "https://{endpoint}/face/v1.0-preview/dynamicpersongroups/{dynamicPersonGroupId}";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("name", "Example DynamicPersonGroup");
body.Add("userData", "User defined data");
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PutAsync(uri, content);
}

此程序是即時的,不需要等待任何非同步作業成功。

或者,您可以在 AddPersonIds 引數中提供一組人員識別碼,用以建立在一開始就包含這些參考的群組:

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

var uri = "https://{endpoint}/face/v1.0-preview/dynamicpersongroups/{dynamicPersonGroupId}";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("name", "Example DynamicPersonGroup");
body.Add("userData", "User defined data");
body.Add("addPersonIds", new List<string>{"{guid1}", "{guid2}", …});
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PutAsync(uri, content);

    // Async operation location to query the completion status from
    var operationLocation = response.Headers.Get("Operation-Location");
}

注意

一旦呼叫傳回,已建立的 DynamicPersonGroup 即可在識別呼叫中使用,並在程序中提供任何人員參考。 另一方面,傳回的作業識別碼的完成狀態表示「人員對群組」關聯性的更新狀態。

更新 DynamicPersonGroup

初始建立後,您可以使用「更新動態人員群組 API」來新增和移除 DynamicPersonGroup 中的人員參考。 若要將 Person 物件新增至群組,請在 addPersonsIds 引數中列出人員識別碼。 若要移除人員物件,請在 removePersonIds 引數中將其列出。 新增和移除可以在單一呼叫中執行:

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

var uri = "https://{endpoint}/face/v1.0-preview/dynamicpersongroups/{dynamicPersonGroupId}";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("name", "Example Dynamic Person Group updated");
body.Add("userData", "User defined data updated");
body.Add("addPersonIds", new List<string>{"{guid1}", "{guid2}", …});
body.Add("removePersonIds", new List<string>{"{guid1}", "{guid2}", …});
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PatchAsync(uri, content);

    // Async operation location to query the completion status from
    var operationLocation = response.Headers.Get("Operation-Location");
}

呼叫傳回後,就會在查詢群組時反映集合的更新。 如同建立 API,傳回的作業會指出涉及更新的任何的「人員-群組」關聯性的更新狀態。 在對群組進行進一步的更新呼叫之前,不需要等待作業完成。

識別 PersonDirectory 中的臉部

PersonDirectory 中使用臉部資料的常見方式,首推將已註冊的人員物件與指定的臉部進行比較,並識別最有可能屬於哪個候選項目。 在要求中可提供多個臉部,每個臉部都會在回應中收到本身的比較結果集。

PersonDirectory 中,每個臉部有三種類型的範圍可供識別:

案例 1:對 DynamicPersonGroup 進行識別

在要求中指定 dynamicPersonGroupId 屬性,會將臉部與群組中參考的每個進行比較。 在一個呼叫中只能對單一 DynamicPersonGroup 進行識別。

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

// Optional query strings for more fine grained face control
var uri = "https://{endpoint}/face/v1.0-preview/identify";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("faceIds", new List<string>{"{guid1}", "{guid2}", …});
body.Add("dynamicPersonGroupId", "{dynamicPersonGroupIdToIdentifyIn}");
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PostAsync(uri, content);
}

案例 2:對特定人員清單進行識別

您也可以在 personIds 屬性中指定人員識別碼清單,將臉部與其一一比較。

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");
            
var uri = "https://{endpoint}/face/v1.0-preview/identify";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("faceIds", new List<string>{"{guid1}", "{guid2}", …});
body.Add("personIds", new List<string>{"{guid1}", "{guid2}", …});
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PostAsync(uri, content);
}

案例 3:對整個 PersonDirectory 進行識別

在要求的 personIds 屬性中提供單一星號,會將臉部與註冊於 PersonDirectory 中的每個進行比較。

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");
            
var uri = "https://{endpoint}/face/v1.0-preview/identify";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("faceIds", new List<string>{"{guid1}", "{guid2}", …});
body.Add("personIds", new List<string>{"*"});
byte[] byteData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PostAsync(uri, content);
}

在這三個案例中,識別只會將傳入的臉部與 AddPersonFace 呼叫傳回了「成功」回應的臉部進行比較。

PersonDirectory 中的人員驗證臉部

透過從偵測呼叫傳回的臉部識別碼,您可以確認臉部是否屬於在 PersonDirectory 內註冊的特定人員。 使用 personId 屬性指定人員

var client = new HttpClient();

// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

var uri = "https://{endpoint}/face/v1.0-preview/verify";

HttpResponseMessage response;

// Request body
var body = new Dictionary<string, object>();
body.Add("faceId", "{guid1}");
body.Add("personId", "{guid1}");
var jsSerializer = new JavaScriptSerializer();
byte[] byteData = Encoding.UTF8.GetBytes(jsSerializer.Serialize(body));

using (var content = new ByteArrayContent(byteData))
{
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    response = await client.PostAsync(uri, content);
}

回應會包含布林值,指出服務是否將新的臉部視為屬於相同人員,以及預測的信賴分數。

下一步

在本指南中,您已了解如何使用 PersonDirectory 結構來儲存臉部應用程式的臉部和人員資料。 接下來,請了解新增使用者臉部資料的最佳做法。