Använda attributet HeadPose
I den här guiden får du se hur du kan använda attributet HeadPose för ett identifierat ansikte för att aktivera vissa viktiga scenarier.
Rotera ansiktsrektangeln
Ansiktsrektangeln, som returneras med varje identifierat ansikte, markerar ansiktets plats och storlek i bilden. Som standard justeras rektangeln alltid med bilden (sidorna är lodräta och vågräta). Detta kan vara ineffektivt för inramning av vinklade ansikten. I situationer där du vill beskära ansikten programmatiskt i en bild är det bättre att kunna rotera rektangeln för beskärning.
Exempelappen Cognitive Services ansikts-WPF (Windows Presentation Foundation) använder attributet HeadPose för att rotera dess identifierade ansiktsrektanglar.
Utforska exempelkoden
Du kan programmatiskt rotera ansiktsrektangeln med hjälp av attributet HeadPose. Om du anger det här attributet när du identifierar ansikten (se Anropa API:etför identifiering) kommer du att kunna köra frågor mot det senare. Följande metod från appen Cognitive Services WPF för ansiktsansiktet tar en lista över DetectedFace-objekt och returnerar en lista över ansiktsobjekt. Ansikte här är en anpassad klass som lagrar ansiktsdata, inklusive uppdaterade rektangelkoordinater. Nya värden beräknas för övre, vänstra , bredd och höjd, och ett nytt fält FaceAngle anger rotationen.
/// <summary>
/// Calculate the rendering face rectangle
/// </summary>
/// <param name="faces">Detected face from service</param>
/// <param name="maxSize">Image rendering size</param>
/// <param name="imageInfo">Image width and height</param>
/// <returns>Face structure for rendering</returns>
public static IEnumerable<Face> CalculateFaceRectangleForRendering(IList<DetectedFace> faces, int maxSize, Tuple<int, int> imageInfo)
{
var imageWidth = imageInfo.Item1;
var imageHeight = imageInfo.Item2;
var ratio = (float)imageWidth / imageHeight;
int uiWidth = 0;
int uiHeight = 0;
if (ratio > 1.0)
{
uiWidth = maxSize;
uiHeight = (int)(maxSize / ratio);
}
else
{
uiHeight = maxSize;
uiWidth = (int)(ratio * uiHeight);
}
var uiXOffset = (maxSize - uiWidth) / 2;
var uiYOffset = (maxSize - uiHeight) / 2;
var scale = (float)uiWidth / imageWidth;
foreach (var face in faces)
{
var left = (int)(face.FaceRectangle.Left * scale + uiXOffset);
var top = (int)(face.FaceRectangle.Top * scale + uiYOffset);
// Angle of face rectangles, default value is 0 (not rotated).
double faceAngle = 0;
// If head pose attributes have been obtained, re-calculate the left & top (X & Y) positions.
if (face.FaceAttributes?.HeadPose != null)
{
// Head pose's roll value acts directly as the face angle.
faceAngle = face.FaceAttributes.HeadPose.Roll;
var angleToPi = Math.Abs((faceAngle / 180) * Math.PI);
// _____ | / \ |
// |____| => |/ /|
// | \ / |
// Re-calculate the face rectangle's left & top (X & Y) positions.
var newLeft = face.FaceRectangle.Left +
face.FaceRectangle.Width / 2 -
(face.FaceRectangle.Width * Math.Sin(angleToPi) + face.FaceRectangle.Height * Math.Cos(angleToPi)) / 2;
var newTop = face.FaceRectangle.Top +
face.FaceRectangle.Height / 2 -
(face.FaceRectangle.Height * Math.Sin(angleToPi) + face.FaceRectangle.Width * Math.Cos(angleToPi)) / 2;
left = (int)(newLeft * scale + uiXOffset);
top = (int)(newTop * scale + uiYOffset);
}
yield return new Face()
{
FaceId = face.FaceId?.ToString(),
Left = left,
Top = top,
OriginalLeft = (int)(face.FaceRectangle.Left * scale + uiXOffset),
OriginalTop = (int)(face.FaceRectangle.Top * scale + uiYOffset),
Height = (int)(face.FaceRectangle.Height * scale),
Width = (int)(face.FaceRectangle.Width * scale),
FaceAngle = faceAngle,
};
}
}
Visa den uppdaterade rektangeln
Härifrån kan du använda de returnerade ansiktsobjekten på skärmen. Följande rader från FaceDetectionPage.xaml visar hur den nya rektangeln återges från dessa data:
<DataTemplate>
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="#FF26B8F4" StrokeThickness="1">
<Rectangle.LayoutTransform>
<RotateTransform Angle="{Binding FaceAngle}"/>
</Rectangle.LayoutTransform>
</Rectangle>
</DataTemplate>
Identifiera huvudgester
Du kan identifiera huvudgester som utfyllnad och skakning av huvud genom att spåra headpose-ändringar i realtid. Du kan använda den här funktionen som en anpassad livenessdetektor.
Livenessidentifiering är uppgiften att fastställa att ett ämne är en verklig person och inte en bild- eller videorepresentation. En huvudgestdetektor kan fungera som ett sätt att verifiera liveness, särskilt i stället för en bildrepresentation av en person.
Varning
Om du vill identifiera huvudgester i realtid måste du anropa ansikts-API:et med hög hastighet (mer än en gång per sekund). Om du har en kostnadsfri nivåprenumeration (f0) är detta inte möjligt. Om du har en betald nivåprenumeration kontrollerar du att du har beräknat kostnaderna för att göra snabba API-anrop för identifiering av huvudgester.
Ett fungerande exempel på huvudgestsidentifiering finns GitHub ansiktsigenkänningsexempel på ansiktsigenkänning.
Nästa steg
Se Cognitive Services WPF-appen för ansikts GitHub ett fungerande exempel på roterade ansiktsrektanglar. Eller så kan du se appen Face HeadPose Sample, som spårar attributet HeadPose i realtid för att identifiera huvudförflyttningar.