Sdílet prostřednictvím


Použití atributu HeadPose

V této příručce se dozvíte, jak pomocí atributu HeadPose rozpoznané tváře povolit některé klíčové scénáře.

Důležité

Atributy tváře se predikují pomocí statistických algoritmů. Nemusí být vždy přesné. Při rozhodování na základě dat atributů buďte opatrní. Vyhýbejte se používání těchto atributů pro falšování identity. Místo toho doporučujeme používat detekci rozpoznávání tváře. Další informace najdete v kurzu: Detekce živých tváří.

Otočení obdélníku tváře

Obdélník tváře vrácený s každým rozpoznaným obličejem označuje umístění a velikost tváře na obrázku. Ve výchozím nastavení je obdélník vždy zarovnán s obrázkem (jeho strany jsou svislé a vodorovné); to může být neefektivní pro rámování šikmých tváří. V situacích, kdy chcete v obrázku oříznout tváře prostřednictvím kódu programu, je lepší obdélník otočit a oříznout.

Ukázková aplikace Azure AI Face WPF (Windows Presentation Foundation) používá atribut HeadPose k otočení rozpoznaných obdélníků tváře.

Prozkoumání ukázkového kódu

Obdélník tváře můžete programově otočit pomocí atributu HeadPose. Pokud tento atribut zadáte při zjišťování tváří (viz Volání rozhraní API pro rozpoznávání), budete ho moct později dotazovat. Následující metoda z aplikace Azure AI Face WPF vezme seznam FaceDetectionResult objekty a vrátí seznam objektů Face . Tvář zde je vlastní třída, která ukládá data tváře, včetně aktualizovaných souřadnic obdélníku. Nové hodnoty se počítají pro horní, levou, šířku a výšku a nové pole FaceAngle určuje otočení.

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

Zobrazení aktualizovaného obdélníku

Odsud můžete použít vrácené objekty tváře ve svém displeji. Následující řádky z FaceDetectionPage.xaml ukazují, jak se nový obdélník vykresluje z těchto dat:

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

Další kroky