HeadPose 属性を使用する

このガイドでは、検出された顔の HeadPose 属性を使用していくつかの重要なシナリオを実現する方法について説明します。

顔の四角形を回転する

顔矩形は、検出される顔ごとに返されますが、これはイメージ内の顔の位置とサイズをマーク付けします。 既定では、この四角形は常に (辺は垂直方向および水平方向) イメージに揃えますが、顔が傾斜している場合は合わせるのが非効率になります。 プログラムでイメージ内の顔をトリミングする場合、トリミングする四角形を回転する方が良いでしょう。

Cognitive Services Face WPF (Windows Presentation Foundation) サンプル アプリでは、HeadPose 属性を使用して、検出された顔の長方形を回転します。

サンプル コードの検証

HeadPose 属性を使用すれば、顔矩形を回転するようプログラミングできます。 顔を検出する際に、この属性を指定する場合 (「検出 API を呼び出す」を参照)、クエリは後で実行きます。 Cognitive Services Face WPFアプリの次のメソッドから、 DetectedFaceオブジェクトの一覧を取得しFaceオブジェクトの一覧を返します。 ここで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>

頭のジェスチャを検出する

HeadPose の変化をリアルタイムで追跡することで、うなずきや頭の揺れのような頭のジェスチャを検出することができます。 この機能をカスタムのライブネス検出器として使用できます。

ライブネス検出とは、対象が実在の人物であって画像やビデオの表現ではないと判定するタスクのことです。 頭のジェスチャの検出器は、特に人の画像表現と区別してライブネスを検証するために役立つ 1 つの方法として機能する可能性があります。

注意事項

頭のジェスチャをリアルタイムで検出するには、Face API を高速に (1 秒に 1 回より多く) 呼び出す必要があります。 Free レベル (f0) サブスクリプションをご利用の場合、これは不可能です。 有料レベルのサブスクリプションをご利用の場合、頭のジェスチャ検出のための高速 API 呼び出しのコストを計算済みであることを確認してください。

頭のジェスチャ検出の実施例については、GitHub の Face HeadPose Sample を参照してください。

次のステップ

回転した顔矩形の実施例については、GitHub の Cognitive Services Face WPF アプリを参照してください。 または、Face HeadPose Sample アプリを参照してください。HeadPose 属性をリアルタイムに追跡して頭の動きを検出します。