Efectos para analizar fotogramas de cámara

En este artículo se describe cómo usar SceneAnalysisEffect y FaceDetectionEffect para analizar el contenido de la secuencia de vista previa de captura multimedia.

Efecto de análisis de escena

La clase SceneAnalysisEffect analiza los fotogramas de vídeo en la secuencia de vista previa de captura multimedia y recomienda opciones de procesamiento para mejorar el resultado de la captura. Actualmente, el efecto admite detectar si la captura podría mejorarse mediante el uso de procesamiento de alto intervalo dinámico (HDR).

Si el efecto recomienda usar HDR, puedes hacerlo de las siguientes maneras:

Espacios de nombres de análisis de escena

Para usar el análisis de la escena, tu aplicación debe incluir los siguientes espacios de nombres, además de los espacios de nombres necesarios para la captura multimedia básica.

using Windows.Media.Core;
using Windows.Media.Devices;

Iniciar el análisis de la escena y añadirlo a la secuencia de vista previa

Efectos de vídeo se implementan mediante dos API, una definición de efecto, que proporciona la configuración que necesita el dispositivo de captura inicializar el efecto, y una instancia de efecto, que puede usarse para controlar el efecto. Dado que seguramente quieras obtener acceso a la instancia de efecto desde varias ubicaciones dentro del código, por lo general deberás declarar una variable de miembro que contenga el objeto.

private SceneAnalysisEffect _sceneAnalysisEffect;

En la aplicación, después de inicializar el objeto MediaCapture, crea una nueva instancia de SceneAnalysisEffectDefinition.

Registra el efecto con el dispositivo de captura llamando a AddVideoEffectAsync en el objeto MediaCapture mediante SceneAnalysisEffectDefinition y especificando MediaStreamType.VideoPreview, para indicar que el efecto debe aplicarse en la secuencia de vista previa del vídeo, en lugar de en la secuencia de captura. AddVideoEffectAsync devuelve una instancia del efecto agregado. Dado que este método puede usarse con varios tipos de efecto, se debe convertir la instancia devuelta a un objeto SceneAnalysisEffect.

Para recibir los resultados del análisis de la escena, debes registrar un controlador para el evento SceneAnalyzed.

Actualmente, el efecto de análisis de escena solo incluye el analizador de alto intervalo dinámico. Habilita el análisis de HDR estableciendo la propiedad HighDynamicRangeControl.Enabled del efecto en true.

// Create the definition
var definition = new SceneAnalysisEffectDefinition();

// Add the effect to the video record stream
_sceneAnalysisEffect = (SceneAnalysisEffect)await _mediaCapture.AddVideoEffectAsync(definition, MediaStreamType.VideoPreview);

// Subscribe to notifications about scene information
_sceneAnalysisEffect.SceneAnalyzed += SceneAnalysisEffect_SceneAnalyzed;

// Enable HDR analysis
_sceneAnalysisEffect.HighDynamicRangeAnalyzer.Enabled = true;

Implementa el controlador de eventos SceneAnalyzed

Los resultados del análisis de la escena se devuelven en el controlador de eventos SceneAnalyzed. El objeto SceneAnalyzedEventArgs pasado al controlador tiene un objeto SceneAnalysisEffectFrame que tiene un objeto HighDynamicRangeOutput. La propiedad Certainty de la salida de alto intervalo dinámico proporciona un valor entre 0 y 1,0, donde 0 indica que el procesamiento de HDR no podría ayudar a mejorar los resultados de la captura y 1,0 indica que el procesamiento de HDR podría ayudar. Puedes decidir el punto de umbral en el que quieres usar HDR, o mostrar los resultados al usuario y que el usuario decida.

private void SceneAnalysisEffect_SceneAnalyzed(SceneAnalysisEffect sender, SceneAnalyzedEventArgs args)
{
    double hdrCertainty = args.ResultFrame.HighDynamicRange.Certainty;
    
    // Certainty value is between 0.0 and 1.0
    if(hdrCertainty > MyCertaintyCap)
    {
        ShowMessageToUser("Enabling HDR capture is recommended.");
    }
}

El objeto HighDynamicRangeOutput pasado al controlador también tiene una propiedad FrameControllers que contiene los controladores de fotograma sugeridos para capturar una secuencia fotográfica variable para el procesamiento de HDR. Para obtener más información, vea Secuencia de fotos variables.

Limpiar el efecto de análisis de la escena

Cuando la aplicación haya terminado de capturar, antes de eliminar el objeto MediaCapture, debes deshabilitar el efecto de análisis de la escena estableciendo la propiedad HighDynamicRangeAnalyzer.Enabled del efecto en "false", y anular el registro del controlador de eventos SceneAnalyzed. Llama a MediaCapture.ClearEffectsAsync, especificando el flujo de vista previa del vídeo, ya que ese era el flujo al que se agregó el efecto. Por último, establece la variable de miembro en "null".

// Disable detection
_sceneAnalysisEffect.HighDynamicRangeAnalyzer.Enabled = false;

_sceneAnalysisEffect.SceneAnalyzed -= SceneAnalysisEffect_SceneAnalyzed;

// Remove the effect from the preview stream
await _mediaCapture.ClearEffectsAsync(MediaStreamType.VideoPreview);

// Clear the member variable that held the effect instance
_sceneAnalysisEffect = null;

Efecto de detección de rostros

La clase FaceDetectionEffect identifica la ubicación de rostros dentro de la secuencia de vista previa de captura multimedia. El efecto te permite recibir una notificación siempre que se detecta en la secuencia de vista previa de una cara y proporciona el cuadro de límite para cada rostro detectado en el plazo de vista previa. En dispositivos compatibles, el efecto de detección de rostro también proporciona la exposición mejorada y centrarse en la cara más importante de la escena.

Espacios de nombres de detección de rostros

Para usar la detección de rostros, tu aplicación debe incluir los siguientes espacios de nombres además de los espacios de nombres necesarios para la captura multimedia básica.

using Windows.Media.Core;

Iniciar el efecto de detección de rostros y añadirlo a la secuencia de vista previa

Efectos de vídeo se implementan mediante dos API, una definición de efecto, que proporciona la configuración que necesita el dispositivo de captura inicializar el efecto, y una instancia de efecto, que puede usarse para controlar el efecto. Dado que seguramente quieras obtener acceso a la instancia de efecto desde varias ubicaciones dentro del código, por lo general deberás declarar una variable de miembro que contenga el objeto.

FaceDetectionEffect _faceDetectionEffect;

En la aplicación, después de inicializar el objeto MediaCapture, crea una nueva instancia de FaceDetectionEffectDefinition. Establecer la propiedad DetectionMode para priorizar la rapidez o la precisión de la detección de rostros. Establece SynchronousDetectionEnabled para especificar que las tramas entrantes no se retrasen esperando que se complete la detección de rostros, ya que esto puede provocar una experiencia de vista previa entrecortada.

Registra el efecto con el dispositivo de captura llamando a AddVideoEffectAsync en tu objeto MediaCapture mediante FaceDetectionEffectDefinition y especificando MediaStreamType.VideoPreview para indicar que el efecto debe aplicarse en la secuencia de vista previa de vídeo, en lugar de la secuencia de captura. AddVideoEffectAsync devuelve una instancia del efecto agregado. Dado que este método puede usarse con varios tipos de efecto, se debe convertir la instancia devuelta a un objeto FaceDetectionEffect.

Habilita o deshabilita el efecto estableciendo la propiedad FaceDetectionEffect.Enabled. Ajusta la frecuencia con que el efecto analiza los fotogramas estableciendo la propiedad FaceDetectionEffect.DesiredDetectionInterval. Estas dos propiedades se pueden ajustar mientras se está realizando la captura multimedia.


// Create the definition, which will contain some initialization settings
var definition = new FaceDetectionEffectDefinition();

// To ensure preview smoothness, do not delay incoming samples
definition.SynchronousDetectionEnabled = false;

// In this scenario, choose detection speed over accuracy
definition.DetectionMode = FaceDetectionMode.HighPerformance;

// Add the effect to the preview stream
_faceDetectionEffect = (FaceDetectionEffect)await _mediaCapture.AddVideoEffectAsync(definition, MediaStreamType.VideoPreview);

// Choose the shortest interval between detection events
_faceDetectionEffect.DesiredDetectionInterval = TimeSpan.FromMilliseconds(33);

// Start detecting faces
_faceDetectionEffect.Enabled = true;

Recibir notificaciones cuando se detectan rostros

Si quieres realizar alguna acción cuando se detectan rostros, como dibujar un cuadro alrededor de los rostros detectados en la vista previa del vídeo, puedes registrarte en los eventos FaceDetected.

// Register for face detection events
_faceDetectionEffect.FaceDetected += FaceDetectionEffect_FaceDetected;

En el controlador para el evento, puedes obtener una lista de todos los rostros detectados en un marco si accedes a la propiedad FaceDetectionEffectFrame.DetectedFaces de la clase FaceDetectedEventArgs. La propiedad FaceBox es una estructura BitmapBounds que describe el rectángulo que contiene el rostro detectado en unidades con respecto a las dimensiones de la secuencia de vista previa. Para ver código de ejemplo que transforma las coordenadas de la secuencia de vista previa en coordenadas de pantalla, consulta face detection UWP sample (Muestra de UWP de detección de rostro).

private void FaceDetectionEffect_FaceDetected(FaceDetectionEffect sender, FaceDetectedEventArgs args)
{
    foreach (Windows.Media.FaceAnalysis.DetectedFace face in args.ResultFrame.DetectedFaces)
    {
        BitmapBounds faceRect = face.FaceBox;

        // Draw a rectangle on the preview stream for each face
    }
}

Limpiar el efecto de detección de rostro

Cuando la aplicación haya terminado capturar, antes de eliminar el objeto MediaCapture, deberías deshabilitar el efecto de detección de rostros con FaceDetectionEffect.Enabled y anular el registro del controlador de eventos FaceDetected, si has registrado uno anteriormente. Llama a MediaCapture.ClearEffectsAsync, especificando el flujo de vista previa del vídeo, ya que ese era el flujo al que se agregó el efecto. Por último, establece la variable de miembro en "null".

// Disable detection
_faceDetectionEffect.Enabled = false;

// Unregister the event handler
_faceDetectionEffect.FaceDetected -= FaceDetectionEffect_FaceDetected;

// Remove the effect from the preview stream
await _mediaCapture.ClearEffectsAsync(MediaStreamType.VideoPreview);

// Clear the member variable that held the effect instance
_faceDetectionEffect = null;

Comprobar la compatibilidad del foco y la exposición de rostros detectados

No todos los dispositivos tienen un dispositivo de captura que puede ajustar el foco y la exposición en función de rostros detectados. Dado que la detección de rostro consume recursos del dispositivo, puede que solo desees habilitar la detección de rostro en dispositivos que pueden usar la característica para mejorar la captura. Para ver si la optimización de captura de rostros está disponible, obtén el VideoDeviceController para tu MediaCapture inicializado y luego el RegionsOfInterestControl del controlador de dispositivo de vídeo. Comprueba si MaxRegions admite al menos una región. Luego comprueba si AutoExposureSupported o AutoFocusSupported son true. Si se cumplen estas condiciones, el dispositivo puede aprovechar la detección de rostros para mejorar la captura.

var regionsControl = _mediaCapture.VideoDeviceController.RegionsOfInterestControl;
bool faceDetectionFocusAndExposureSupported =
    regionsControl.MaxRegions > 0 &&
    (regionsControl.AutoExposureSupported || regionsControl.AutoFocusSupported);