你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 HeadPose 属性

本指南介绍如何使用检测到的人脸的 HeadPose 属性来启用某些重要方案。

重要

人脸属性是使用统计算法预测的, 不一定准确。 根据特性数据做出决策时请小心。 请避免使用这些属性进行反欺骗。 我们建议改用人脸活体检测。 有关详细信息,请参阅教程:检测人脸活性

旋转人脸矩形

随每个检测到的人脸返回的人脸矩形用于标记人脸在图像中的位置和大小。 默认情况下,此矩形始终与图像(其边分为垂直边和水平边)对齐;在给有一定角度的人脸配框时,这可能导致效率不高。 在需要以编程方式对图像中的人脸进行裁剪的情况下,最好是能够旋转要裁剪的矩形。

Azure AI 人脸 WPF (Windows Presentation Foundation) 示例应用使用 HeadPose 属性来旋转其检测到的人脸矩形。

探索示例代码

可使用 HeadPose 属性以编程方式旋转人脸矩形。 如果在检测人脸(请参阅调用检测 API)时指定此属性,可以稍后对其进行查询。 Azure AI 人脸 WPF 应用中的以下方法接受 FaceDetectionResult 对象的列表,并返回 Face 对象的列表。 此处的 Face 是一个自定义类,用于存储人脸数据,包括更新的矩形坐标。 将会针对 topleftwidthheight 计算新值,而新字段 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<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,
        };
    }
}

显示更新的矩形

在这里,可以在显示中使用返回的 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>

后续步骤

  • 有关旋转的人脸矩形的有效示例,请参阅 GitHub 上的 Azure AI 人脸 WPF 应用。