使用 HeadPose 屬性

在本指南中,您將瞭解如何使用偵測到臉部的 HeadPose 屬性來啟用某些重要案例。

重要

臉部屬性是透過使用統計演算法來預測。 它們可能並不總是準確的。 當您根據屬性數據做出決策時,請小心。 請避免使用這些屬性進行反詐騙。 相反地,我們建議使用臉部活躍度偵測。 如需詳細資訊,請參閱 教學課程:偵測臉部中的活躍度。

旋轉臉部矩形

臉部矩形會以每個偵測到的臉部一起傳回,以標記影像中臉部的位置和大小。 根據預設,矩形一律會與影像對齊(其側邊為垂直和水準):對於框架角度的臉部而言,這可能會沒有效率。 如果您想要以程序設計方式裁剪影像中的臉部,最好能夠旋轉矩形來裁剪。

Azure AI Face WPF (Windows Presentation Foundation) 範例應用程式會使用 HeadPose 屬性來旋轉其偵測到的臉部矩形。

探索範例程序代碼

您可以使用 HeadPose 屬性,以程式設計方式旋轉臉部矩形。 如果您在偵測臉部時指定這個屬性(請參閱 呼叫偵測 API),您稍後就能夠查詢它。 Azure AI Face WPF 應用程式的下列方法會採用 DetectedFace 物件清單,並傳回 Face 物件清單。 此處的臉部 是儲存臉部數據的自定義類別,包括更新的矩形座標。 新值會針對 頂端方、 寬度高度計算,而新的欄位 FaceAngle 會指定旋轉。

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

顯示更新後的矩形

您可以從這裡使用顯示中傳 回的 Face 物件。 FaceDetectionPage.xaml 的下列幾行顯示如何從此數據轉譯新的矩形:

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

下一步