Het kenmerk HeadPose gebruiken

In deze handleiding ziet u hoe u het kenmerk HeadPose van een gedetecteerd gezicht kunt gebruiken om enkele belangrijke scenario's mogelijk te maken.

Belangrijk

Gezichtskenmerken worden voorspeld door het gebruik van statistische algoritmen. Ze zijn misschien niet altijd nauwkeurig. Wees voorzichtig wanneer u beslissingen neemt op basis van kenmerkgegevens. Gebruik deze kenmerken niet voor anti-adresvervalsing. In plaats daarvan raden we u aan gezichts livenessdetectie te gebruiken. Raadpleeg de zelfstudie: Liveness in gezichten detecteren voor meer informatie.

De gezichtsrechthoek draaien

De gezichtsrechthoek, geretourneerd met elk gedetecteerd gezicht, markeert de locatie en grootte van het gezicht in de afbeelding. De rechthoek wordt standaard altijd uitgelijnd met de afbeelding (de zijden zijn verticaal en horizontaal); dit kan inefficiƫnt zijn voor het inkaderen van gezichten in een hoek. In situaties waar u op een programmatische manier gezichten wilt bijsnijden in een afbeelding, is het beter om de rechthoek te kunnen draaien om bij te snijden.

De Azure AI Face WPF-voorbeeld-app (Windows Presentation Foundation) gebruikt het kenmerk HeadPose om de gedetecteerde gezichtsrechthoeken te draaien.

De voorbeeldcode verkennen

U kunt de gezichtsrechthoek programmatisch draaien met het kenmerk HeadPose. Als u dit kenmerk opgeeft bij het detecteren van gezichten (zie De detectie-API aanroepen), kunt u deze later opvragen. De volgende methode van de Azure AI Face WPF-app gebruikt een lijst met DetectedFace-objecten en retourneert een lijst met Face-objecten . Face hier is een aangepaste klasse waarmee gezichtsgegevens worden opgeslagen, met inbegrip van de bijgewerkte rechthoekcoƶrdinaten. Nieuwe waarden worden berekend voor bovenkant, links, breedte en hoogte, en een nieuw veld FaceAngle geeft de rotatie op.

/// <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,
        };
    }
}

De bijgewerkte rechthoek weergeven

Hier kunt u de geretourneerde Face-objecten gebruiken in uw weergave. De volgende regels van FaceDetectionPage.xaml laten zien hoe de nieuwe rechthoek wordt weergegeven op basis van deze gegevens:

 <DataTemplate>
    <Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="#FF26B8F4" StrokeThickness="1">
        <Rectangle.LayoutTransform>
            <RotateTransform Angle="{Binding FaceAngle}"/>
        </Rectangle.LayoutTransform>
    </Rectangle>
</DataTemplate>

Volgende stappen

  • Zie de Azure AI Face WPF-app op GitHub voor een werkend voorbeeld van gedraaide gezichtsrechthoeken.
  • U kunt ook de Face HeadPose-voorbeeldapp bekijken, die het kenmerk HeadPose in realtime volgt om hoofdbewegingen te detecteren.