Použití struktury PersonDirectory

Aby mohli zákazníci rozhraní API pro rozpoznávání tváře provádět operace rozpoznávání tváře, jako je identifikace a hledání podobných, musí vytvořit seznam objektů Person (Osoba). Nový adresář PersonDirectory je datová struktura, která obsahuje jedinečná ID, volitelné názvové řetězce a volitelné řetězce metadat uživatele pro každou identitu osoby přidanou do adresáře.

Rozhraní API pro rozpoznávání tváře v současné době nabízí strukturu LargePersonGroup, která má podobné funkce, ale je omezená na 1 milion identit. Struktura PersonDirectory může škálovat až na 75 milionů identit.

Dalším velkým rozdílem mezi PersonDirectory a předchozími datovými strukturami je to, že po přidání tváří do objektu Person už nebudete muset provádět žádná volání Train, protože proces aktualizace probíhá — automaticky.

Požadavky

  • Předplatné Azure – Vytvořte si ho zdarma.
  • Jakmile budete mít předplatné Azure, vytvořte prostředek Face v Azure Portal a získejte svůj klíč a koncový bod. Po nasazení klikněte na Přejít k prostředku.
    • K připojení aplikace k rozhraní API pro rozpoznávání tváře budete potřebovat klíč a koncový bod z prostředku, který vytvoříte. Klíč a koncový bod vložíte do následujícího kódu.
    • K vyzkoušejí služby můžete použít bezplatnou cenovou úroveň (F0) a později upgradovat na placenou úroveň pro produkční prostředí.

Přidání osob do adresáře PersonDirectory

Osoby jsou základními jednotkami registrace v adresáři PersonDirectory. Po přidání osoby do adresáře můžete k této osobě přidat až 248 obrázků tváří na jeden model rozpoznávání. Pak můžete pomocí různých oborů identifikovat tváře proti nim.

Vytvoření osoby

Pokud chcete vytvořit osobu, musíte zavolat rozhraní API CreatePerson a zadat název nebo hodnotu vlastnosti 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); 
}

Volání CreatePerson vrátí vygenerované ID osoby a umístění operace. Data Osob se zpracují asynchronně, takže k načtení výsledků použijete umístění operace.

Čekání na dokončení asynchronní operace

Ke kontrole průběhu budete muset zadat dotaz na stav asynchronní operace pomocí vráceného řetězce umístění operace.

Nejprve byste měli definovat datový model, jako je následující, který bude zpracovávat stavovou odpověď.

[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; }
}

Pomocí výše uvedené zprávy HttpResponseMessage se pak můžete dotazovat na adresu URL a čekat na výsledky.

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

Jakmile se stav vrátí jako "úspěch", objekt Person se považuje za přidaný do adresáře.

Poznámka

Asynchronní operace volání Create Person nemusí před přidáním tváří zobrazovat stav "úspěch", ale musí být dokončena před přidáním osoby do DynamicPersonGroup (viz níže Vytvoření a aktualizace DynamicPersonGroup) nebo porovnání během volání Identify. Ověřte, že volání budou fungovat okamžitě po úspěšném přidání tváří do person.

Přidání tváří do osob

Jakmile budete mít ID osoby z volání Create Person (Vytvořit osobu), můžete do modelu rozpoznávání osob přidat až 248 obrázků tváří. Zadejte model rozpoznávání (a volitelně model detekce), který se má použít ve volání, protože data v každém modelu rozpoznávání budou zpracována samostatně v adresáři PersonDirectory.

Aktuálně podporované modely rozpoznávání jsou:

  • Recognition_02
  • Recognition_03
  • Recognition_04

Pokud obrázek obsahuje více tváří, budete muset zadat obdélníkový ohraničující rámeček pro tvář, která je zamýšleným cílem. Následující kód přidá tváře do objektu Person.

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

Po volání funkce Přidat tváře se data tváře zpracují asynchronně a stejně jako předtím budete muset počkat na úspěch operace.

Po dokončení operace sčítání tváře budou data připravená na volání Identify.

Vytvoření a aktualizace DynamicPersonGroup

DynamicPersonGroups jsou kolekce odkazů na objekty Person v rámci PersonDirectory. Slouží k vytváření podmnožiny adresáře. Běžně se používá, když chcete v operaci Identify získat méně falešně pozitivních výsledků a vyšší přesnost tím, že omezíte rozsah pouze na objekty Person, které očekáváte, že se shodují. Mezi případy praktického použití patří adresáře pro konkrétní přístup k budově v rámci většího areálu nebo organizace. Adresář organizace může obsahovat 5 milionů jednotlivců, ale konkrétní budovu potřebujete prohledávat jenom 800 lidí, takže byste vytvořili skupinu DynamicPersonGroup obsahující tyto konkrétní jednotlivce.

Pokud jste už skupinu PersonGroup používali, poznamenejte si dva hlavní rozdíly:

  • Každá osoba uvnitř skupiny DynamicPersonGroup je odkazem na skutečnou osobu v adresáři PersonDirectory, což znamená, že není nutné znovu vytvořit osobu v každé skupině.
  • Jak je uvedeno v předchozích částech, není potřeba provádět volání Train, protože data o tvářích se zpracovávají automaticky na úrovni adresáře.

Vytvoření skupiny

Pokud chcete vytvořit skupinu DynamicPersonGroup, musíte zadat ID skupiny s alfanumerickými znaky nebo pomlčkami. Toto ID bude fungovat jako jedinečný identifikátor pro všechny účely použití skupiny.

Kolekci skupin můžete inicializovat dvěma způsoby. Na začátku můžete vytvořit prázdnou skupinu a naplnit ji později:

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

Tento proces je okamžitý a není nutné čekat na úspěšné provádění všech asynchronních operací.

Případně můžete vytvořit sadu ID osob, která bude obsahovat tyto odkazy od začátku, a to tak, že sadu poskytnete v argumentu 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");
}

Poznámka

Jakmile se volání vrátí, vytvořená skupina DynamicPersonGroup bude připravena k použití ve volání Identify s libovolnými odkazy person poskytnutými v procesu. Stav dokončení vráceného ID operace na druhé straně označuje stav aktualizace vztahu osoba-skupina.

Aktualizace DynamicPersonGroup

Po počátečním vytvoření můžete pomocí rozhraní API pro aktualizaci dynamické skupiny osob přidat a odebrat odkazy na osobu ze skupiny DynamicPersonGroup. Pokud chcete do skupiny přidat objekty Person, vypište ID osob v argumentu addPersonsIds. Pokud chcete odebrat objekty Person, vypište je v argumentu removePersonIds. Přidání i odebrání lze provést v jednom volání:

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

Jakmile se volání vrátí, aktualizace kolekce se projeví při dotazech na skupinu. Stejně jako u rozhraní API pro vytváření indikuje vrácená operace stav aktualizace vztahu osoba-skupina pro každou osobu, která je součástí aktualizace. Před provedením dalších volání aktualizace do skupiny nemusíte čekat na dokončení operace.

Identifikace tváří v adresáři PersonDirectory

Nejběžnějším způsobem, jak používat data tváří v adresáři PersonDirectory, je porovnat zaregistrované objekty Person s danou tváří a identifikovat nejpravděpodobnějšího kandidáta, do které patří. V požadavku může být k dispozici více tváří a každá z nich obdrží vlastní sadu výsledků porovnání v odpovědi.

V adresáři PersonDirectory existují tři typy oborů, pro které je možné identifikovat jednotlivé tváře:

Scénář 1: Identifikace proti DynamicPersonGroup

Zadáním vlastnosti dynamicPersonGroupId v požadavku porovnáte tvář s každou osobou, na kterou ve skupině odkazuje. Ve volání lze identifikovat pouze jednu skupinu 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);
}

Scénář 2: Určení konkrétního seznamu osob

Můžete také zadat seznam ID osob ve vlastnosti personIds a porovnat tvář s každou z nich.

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

Scénář 3: Identifikace v celém adresáři PersonDirectory

Poskytnutí jedné hvězdičky ve vlastnosti personIds v požadavku porovná tvář s každou osobou zaregistrovanou v adresáři 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);
}

Ve všech třech scénářích identifikace porovná pouze příchozí tvář s tvářemi, jejichž volání AddPersonFace se vrátilo s odpovědí "úspěch".

Ověření tváří proti osobám v adresáři PersonDirectory

Když se ID tváře vrátí z volání detekce, můžete ověřit, jestli tvář patří konkrétní osobě zaregistrované v adresáři PersonDirectory. Zadejte osobu pomocí vlastnosti 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);
}

Odpověď bude obsahovat logickou hodnotu, která určuje, jestli služba považuje novou tvář za patřit stejné osobě, a skóre spolehlivosti pro předpověď.

Další kroky

V této příručce jste se naučili používat strukturu PersonDirectory k ukládání údajů o tvářích a osob pro vaši aplikaci pro tvář. Dále se seznamte s osvědčenými postupy pro přidání údajů o tvářích uživatelů.