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 escenas

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 la detección de si la captura se mejoraría mediante el procesamiento de rango dinámico alto (HDR).

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

Espacios de nombres de análisis de escenas

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

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

Inicializar el efecto de análisis de escena y agregarlo a la secuencia de vista previa

Los efectos de vídeo se implementan mediante dos API, una definición de efecto, que proporciona la configuración que el dispositivo de captura necesita para inicializar el efecto y una instancia de efecto, que se puede usar para controlar el efecto. Dado que es posible que desee acceder a la instancia de efecto desde varios lugares dentro del código, normalmente debe declarar una variable miembro para contener el objeto.

private SceneAnalysisEffect _sceneAnalysisEffect;

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

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

Para recibir los resultados del análisis de escenas, debe registrar un controlador para el evento SceneAnalyzed.

Actualmente, el efecto de análisis de escenas solo incluye el analizador de rango dinámico alto. Habilite el análisis HDR estableciendo 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;

Implementación del controlador de eventos SceneAnalyzed

Los resultados del análisis de escenas 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 rango dinámico alto proporciona un valor entre 0 y 1.0, donde 0 indica que el procesamiento HDR no ayudaría a mejorar el resultado de la captura y 1.0 indica que el procesamiento HDR ayudaría. Puedes decidir el punto de umbral en el que quieres usar HDR o mostrar los resultados al usuario y permitir 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 controladores de fotogramas sugeridos para capturar una secuencia de fotos variable para el procesamiento HDR. Para obtener más información, vea Secuencia de fotos variable.

Limpieza del efecto de análisis de escenas

Cuando la aplicación haya terminado de capturar, antes de eliminar el objeto MediaCapture, debe deshabilitar el efecto de análisis de escenas estableciendo la propiedad HighDynamicRangeAnalyzer.Enabled del efecto en false y anular el registro del controlador de eventos SceneAnalyzed. Llame a MediaCapture.ClearEffectsAsync, especificando la secuencia de vista previa de vídeo desde que se agregó la secuencia al que se agregó el efecto. Por último, establezca la variable 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 caras

FaceDetectionEffect identifica la ubicación de las caras dentro del flujo de vista previa de captura multimedia. El efecto permite recibir una notificación cada vez que se detecta una cara en la secuencia de vista previa y proporciona el rectángulo de selección para cada cara detectada dentro del marco de vista previa. En los dispositivos compatibles, el efecto de detección de caras también proporciona una exposición mejorada y se centra en la cara más importante de la escena.

Espacios de nombres de detección de caras

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

using Windows.Media.Core;

Inicialice el efecto de detección de caras y agréguelo a la secuencia de vista previa.

Los efectos de vídeo se implementan mediante dos API, una definición de efecto, que proporciona la configuración que el dispositivo de captura necesita para inicializar el efecto y una instancia de efecto, que se puede usar para controlar el efecto. Dado que es posible que desee acceder a la instancia de efecto desde varios lugares dentro del código, normalmente debe declarar una variable miembro para contener el objeto.

FaceDetectionEffect _faceDetectionEffect;

En la aplicación, después de inicializar el objeto MediaCapture, cree una nueva instancia de FaceDetectionEffectDefinition. Establezca la propiedad DetectionMode para priorizar la detección de caras más rápida o una detección de caras más precisa. Establezca SynchronousDetectionEnabled para especificar que los fotogramas entrantes no se retrasan esperando a que se complete la detección de caras, ya que esto puede dar lugar a una experiencia de vista previa corta.

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

Habilite o deshabilite el efecto estableciendo la propiedad FaceDetectionEffect.Enabled. Ajuste la frecuencia con la que el efecto analiza los fotogramas estableciendo la propiedad FaceDetectionEffect.DesiredDetectionInterval. Ambas propiedades se pueden ajustar mientras la captura de medios está en curso.


// 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 caras

Si desea realizar alguna acción cuando se detectan caras, como dibujar un cuadro alrededor de caras detectadas en la vista previa del vídeo, puede registrarse para el evento FaceDetected.

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

En el controlador del evento, puede obtener una lista de todas las caras detectadas en un marco accediendo a la propiedad FaceDetectionEffectFrame.DetectedFaces de FaceDetectedEventArgs. La propiedad FaceBox es una estructura BitmapBounds que describe el rectángulo que contiene la cara detectada en unidades relativas a las dimensiones de flujo de vista previa. Para ver el código de ejemplo que transforma las coordenadas de flujo de vista previa en coordenadas de pantalla, consulta el ejemplo de UWP de detección de caras.

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
    }
}

Limpieza del efecto de detección de caras

Cuando la aplicación haya terminado de capturar, antes de eliminar el objeto MediaCapture, debe deshabilitar el efecto de detección de caras con FaceDetectionEffect.Enabled y anular el registro del controlador de eventos FaceDetected si registró previamente uno. Llame a MediaCapture.ClearEffectsAsync, especificando la secuencia de vista previa de vídeo desde que se agregó la secuencia al que se agregó el efecto. Por último, establezca la variable 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;

Comprobación de la compatibilidad con el foco y la exposición de caras detectadas

No todos los dispositivos tienen un dispositivo de captura que puede ajustar su enfoque y exposición en función de las caras detectadas. Dado que la detección de caras consume recursos de dispositivo, es posible que solo quiera habilitar la detección de caras en los dispositivos que pueden usar la característica para mejorar la captura. Para ver si la optimización de captura basada en caras está disponible, obtenga VideoDeviceController para la clase MediaCapture inicializada y, a continuación, obtenga las regiones de RegionsOfInterestControl del controlador de dispositivo de vídeo. Compruebe si MaxRegions admite al menos una región. A continuación, compruebe si AutoExposureSupported o AutoFocusSupported son true. Si se cumplen estas condiciones, el dispositivo puede aprovechar la detección de caras para mejorar la captura.

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