Как определить атрибуты лица с помощью службы Microsoft Cognitive, предоставив список Windows.Media.FaceAnalysis DetectedFace?

Я могу получить лица с веб-камеры в реальном времени в виде списка Windows.Media.FaceAnalysis DetectedFace объектов. Теперь я хотел бы передать эти лица в Microsoft Cognitive Services API для обнаружения лиц и получения атрибутов лица. Как я могу это сделать?

IList<DetectedFace> faces = null;

// Create a VideoFrame object specifying the pixel format we want our capture image to be (NV12 bitmap in this case).
// GetPreviewFrame will convert the native webcam frame into this format.
const BitmapPixelFormat InputPixelFormat = BitmapPixelFormat.Nv12;
using (VideoFrame previewFrame = new VideoFrame(InputPixelFormat, (int)this.videoProperties.Width, (int)this.videoProperties.Height))
{
    await this.mediaCapture.GetPreviewFrameAsync(previewFrame);

    // The returned VideoFrame should be in the supported NV12 format but we need to verify this.
    if (FaceDetector.IsBitmapPixelFormatSupported(previewFrame.SoftwareBitmap.BitmapPixelFormat))
    {
        faces = await this.faceDetector.DetectFacesAsync(previewFrame.SoftwareBitmap);

        // Now pass this faces to Cognitive services API
        // faceClient.DetectAsync
    }
}

person Joseph Abraham    schedule 20.09.2017    source источник


Ответы (1)


Объект DetectedFace содержит ограничивающую рамку фактического лица. Таким образом, вы можете использовать эти знания для создания потока изображений лица в памяти и отправки его в Клиент лица.

private async Task DetectAsync()
{
    IList<DetectedFace> faces = null;
    const BitmapPixelFormat InputPixelFormat = BitmapPixelFormat.Nv12;
    using (VideoFrame destinationPreviewFrame = new VideoFrame(InputPixelFormat, 640, 480))
    {
        await this._mediaCapture.GetPreviewFrameAsync(destinationPreviewFrame);

        if (FaceDetector.IsBitmapPixelFormatSupported(InputPixelFormat))
        {
            faces = await this.faceDetector.DetectFacesAsync(destinationPreviewFrame.SoftwareBitmap);

            foreach (var face in faces)
            {
                // convert NV12 to RGBA16 format
                SoftwareBitmap convertedBitmap = SoftwareBitmap.Convert(destinationPreviewFrame.SoftwareBitmap, BitmapPixelFormat.Rgba16);

                // get the raw bytes of the detected face
                byte[] rawBytes = await GetBytesFromBitmap(convertedBitmap, BitmapEncoder.BmpEncoderId, face.FaceBox);

                // read the bitmap and send it to the face client
                using (Stream stream = rawBytes.AsBuffer().AsStream())
                {
                    var faceAttributesToReturn = new List<FaceAttributeType>()
                    {
                        FaceAttributeType.Age,
                        FaceAttributeType.Emotion,
                        FaceAttributeType.Hair
                    };

                    Face[] detectedFaces = await this.faceClient.DetectAsync(stream, true, true, faceAttributesToReturn);

                    Debug.Assert(detectedFaces.Length > 0);
                }
            }
        }
    }
}

private async Task<byte[]> GetBytesFromBitmap(SoftwareBitmap soft, Guid encoderId, BitmapBounds bounds)
{
    byte[] array = null;

    using (var ms = new InMemoryRandomAccessStream())
    {
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, ms);
        encoder.SetSoftwareBitmap(soft);

        // apply the bounds of the face
        encoder.BitmapTransform.Bounds = bounds;

        await encoder.FlushAsync();

        array = new byte[ms.Size];

        await ms.ReadAsync(array.AsBuffer(), (uint)ms.Size, InputStreamOptions.None);
    }

    return array;
}
person Maria Ines Parnisari    schedule 24.09.2017
comment
Привет, @Maria Ines Parnisari, спасибо за ответ. Ваш ответ связан с созданием временного файла. Есть ли способ избежать создания временного файла. Можем ли мы создать решение без помощи временного файла? - person Joseph Abraham; 26.09.2017