Använda PersonDirectory-strukturen
För att utföra åtgärder för ansiktsigenkänning, till exempel Identifiera och Hitta liknande, måste ansikts-API-kunder skapa en sorterad lista över personobjekt. Den nya PersonDirectory är en datastruktur som innehåller unika ID:n, valfria namnsträngar och valfria användarmetadatasträngar för varje personidentitet som läggs till i katalogen.
Ansikts-API:et erbjuder för närvarande LargePersonGroup-strukturen, som har liknande funktioner men är begränsad till 1 miljon identiteter. PersonDirectory-strukturen kan skala upp till 75 miljoner identiteter.
En annan viktig skillnad mellan PersonDirectory och tidigare datastrukturer är att du inte längre behöver göra några train-anrop när du har lagt till ansikten i ett Person-objekt som — uppdateringsprocessen sker automatiskt.
Förutsättningar
- Azure-prenumeration – Skapa en utan kostnad.
- När du har din Azure-prenumeration skapar du en ansiktsresurs i Azure Portal för att hämta din nyckel och slutpunkt. När den har distribuerats klickar du på Gå till resurs.
- Du behöver nyckeln och slutpunkten från resursen som du skapar för att ansluta ditt program till ansikts-API:et. Du klistrar in din nyckel och slutpunkt i koden nedan.
- Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.
Lägga till personer i PersonDirectory
Personer är basregistreringsenheterna i PersonDirectory. När du har lagt till en Person i katalogen kan du lägga till upp till 248 ansiktsbilder till den personen, per igenkänningsmodell. Sedan kan du identifiera ansikten mot dem med olika omfång.
Skapa personen
Om du vill skapa en Person måste du anropa API:et CreatePerson och ange ett namn eller userData-egenskapsvärde.
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-anropet returnerar ett genererat ID för personen och en åtgärdsplats. Persondata bearbetas asynkront, så du använder åtgärdsplatsen för att hämta resultatet.
Vänta tills asynkrona åtgärden har slutförts
Du måste fråga statusen för den asynkrona åtgärden med hjälp av den returnerade åtgärdsplatssträngen för att kontrollera förloppet.
Först bör du definiera en datamodell som liknar följande för att hantera statussvaret.
[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; }
}
Med hjälp av HttpResponseMessage ovan kan du sedan avs polla URL:en och vänta på resultat.
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));
När statusen returneras som "lyckades" anses personobjektet ha lagts till i katalogen.
Anteckning
Den asynkrona åtgärden från anropet Skapa person behöver inte visa statusen "lyckades" innan ansikten kan läggas till i den, men den måste slutföras innan personen kan läggas till i en DynamicPersonGroup (se nedan Skapa och uppdatera en DynamicPersonGroup) eller jämföras under ett identifieringsanrop. Kontrollera att anrop fungerar omedelbart efter att ansikten har lagts till i Person.
Lägga till ansikten i Personer
När du har person-ID från anropet Skapa person kan du lägga till upp till 248 ansiktsbilder till en person per igenkänningsmodell. Ange igenkänningsmodellen (och eventuellt identifieringsmodellen) som ska användas i anropet, eftersom data under varje igenkänningsmodell bearbetas separat inuti PersonDirectory.
De igenkänningsmodeller som stöds för närvarande är:
Recognition_02Recognition_03Recognition_04
Om bilden innehåller flera ansikten måste du dessutom ange rektangelrektangeln för ansiktet som är det avsedda målet. Följande kod lägger till ansikten i ett Person-objekt.
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);
}
Efter anropet Lägg till ansikten bearbetas ansiktsdata asynkront och du måste vänta på att åtgärden lyckas på samma sätt som tidigare.
När åtgärden för ansikts additionen är klar är data redo för i Identifiera anrop.
Skapa och uppdatera en DynamicPersonGroup
DynamicPersonGroups är samlingar med referenser till Person-objekt i en PersonDirectory; de används för att skapa delmängder av katalogen. Ett vanligt användningsområde är när du vill få färre falska positiva identifieringar och ökad noggrannhet i en identifieringsåtgärd genom att begränsa omfånget till bara de personobjekt som du förväntar dig att matcha. Praktiska användningsfall omfattar kataloger för specifik åtkomst till en större campus eller organisation. Organisationskatalogen kan innehålla 5 miljoner personer, men du behöver bara söka efter en viss byggnad på 800 personer, så du skapar en DynamicPersonGroup som innehåller just dessa personer.
Om du har använt en PersonGroup tidigare ska du notera två viktiga skillnader:
- Varje person i en DynamicPersonGroup är en referens till den faktiska personen i PersonDirectory, vilket innebär att det inte är nödvändigt att återskapa en Person i varje grupp.
- Som vi nämnde i föregående avsnitt behöver du inte göra train-anrop eftersom ansiktsdata bearbetas på katalognivå automatiskt.
Skapa gruppen
Om du vill skapa en DynamicPersonGroup måste du ange ett grupp-ID med alfanumeriska tecken eller bindestreck. Det här ID:t fungerar som unik identifierare för alla användningsändamål för gruppen.
Det finns två sätt att initiera en gruppsamling. Du kan skapa en tom grupp från början och fylla i den senare:
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);
}
Den här processen är omedelbar och du behöver inte vänta på att asynkrona åtgärder ska lyckas.
Du kan också skapa den med en uppsättning person-ID:t som ska innehålla dessa referenser från början genom att ange uppsättningen i argumentet 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");
}
Anteckning
Så snart anropet returneras är den skapade DynamicPersonGroup redo att användas i ett identifiera-anrop, med alla personreferenser som anges i processen. Slutförandestatusen för det returnerade åtgärds-ID:t anger å andra sidan uppdateringsstatusen för person-till-grupp-relationen.
Uppdatera DynamicPersonGroup
Efter det första skapandet kan du lägga till och ta bort personreferenser från DynamicPersonGroup med API:et Uppdatera dynamisk persongrupp. Om du vill lägga till Person-objekt i gruppen listar du person-ID:t i argumentet addPersonsIds. Om du vill ta bort Person-objekt listar du dem i argumentet removePersonIds. Både att lägga till och ta bort kan utföras i ett enda anrop:
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");
}
När anropet returneras återspeglas uppdateringarna i samlingen när frågor till gruppen efterfrågas. Precis som med API:et för skapande anger den returnerade åtgärden uppdateringsstatusen för person-till-grupp-relationen för alla personer som är inblandade i uppdateringen. Du behöver inte vänta tills åtgärden har slutförts innan du gör ytterligare uppdateringssamtal till gruppen.
Identifiera ansikten i en PersonDirectory
Det vanligaste sättet att använda ansiktsdata i en PersonDirectory är att jämföra de registrerade personobjekten mot ett visst ansikte och identifiera den mest sannolika kandidat som den tillhör. Flera ansikten kan anges i begäran och var och en får en egen uppsättning jämförelseresultat i svaret.
I PersonDirectory finns det tre typer av omfång som varje ansikte kan identifieras mot:
Scenario 1: Identifiera mot en DynamicPersonGroup
Om du anger egenskapen dynamicPersonGroupId i begäran jämförs ansiktet mot varje person som refereras till i gruppen. Endast en DynamicPersonGroup kan identifieras mot i ett anrop.
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);
}
Scenario 2: Identifiera mot en specifik lista över personer
Du kan också ange en lista över person-ID:t i egenskapen personIds för att jämföra ansiktet mot var och en av dem.
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);
}
Scenario 3: Identifiera mot hela PersonDirectory
Om du anger en asterisk i egenskapen personIds i begäran jämförs ansiktet mot varje enskild person som registrerats 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);
}
I alla tre scenarier jämför identifieringen endast det inkommande ansiktet mot ansikten vars AddPersonFace-anrop har returnerats med ett "lyckades"-svar.
Verifiera ansikten mot personer i PersonDirectory
Med ett ansikts-ID som returneras från ett identifieringsanrop kan du kontrollera om ansiktet tillhör en specifik person som registrerats i PersonDirectory. Ange person med egenskapen 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);
}
Svaret innehåller ett booleskt värde som anger om tjänsten anser att det nya ansiktet tillhör samma person och en förtroendepoäng för förutsägelsen.
Nästa steg
I den här guiden har du lärt dig hur du använder PersonDirectory-strukturen för att lagra ansikts- och persondata för din ansiktsapp. Härnäst får du lära dig metodtipsen för att lägga till användarnas ansiktsdata.