Efeitos para análise de quadros de câmera

Este artigo descreve como usar SceneAnalysisEffect e FaceDetectionEffect para analisar o conteúdo do fluxo de visualização de captura de mídia.

Efeito de análise de cena

SceneAnalysisEffect analisa os quadros de vídeo no fluxo de visualização de captura de mídia e recomenda opções de processamento para melhorar o resultado da captura. Atualmente, o efeito permite detectar se a captura poderia ser melhorada usando o processamento em HDR (High Dynamic Range).

Se o efeito recomendar o uso de HDR, você pode fazer isso das seguintes maneiras:

Namespaces de análise de cena

Para usar a análise de cena, seu aplicativo deve incluir os namespaces a seguir, além dos namespaces necessários para a captura de mídia básica.

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

Inicializar o efeito de análise de cena e adicioná-lo ao fluxo de visualização

Os efeitos de vídeo são implementados usando-se duas APIs, uma definição de efeito, que fornece as configurações que o dispositivo de captura precisa para inicializar o efeito, e uma instância de efeito, que pode ser usada para controlar o efeito. Como você pode querer acessar a instância de efeito de vários locais dentro do seu código, normalmente você deve declarar uma variável de membro para manter o objeto.

private SceneAnalysisEffect _sceneAnalysisEffect;

No seu aplicativo, depois de você ter inicializado o objeto MediaCapture, crie uma nova instância de SceneAnalysisEffectDefinition.

Registre o efeito com o dispositivo de captura chamando AddVideoEffectAsync no seu objeto MediaCapture, fornecendo SceneAnalysisEffectDefinition e especificando MediaStreamType.VideoPreview para indicar que o efeito deve ser aplicado ao fluxo de visualização de vídeo, em vez do fluxo de captura. AddVideoEffectAsync retorna uma instância do efeito adicionado. Como esse método pode ser usado com vários tipos de efeito, você deve converter a instância retornada em um objeto SceneAnalysisEffect.

Para receber os resultados da análise de cena, você deve registrar um manipulador para o evento SceneAnalyzed.

Atualmente, o efeito de análise de cena inclui somente o analisador de HDR. Habilite a análise de HDR definindo o efeito HighDynamicRangeControl.Enabled como 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;

Implementar o manipulador de eventos SceneAnalyzed

Os resultados da análise de cena são retornados no manipulador de eventos SceneAnalyzed. O objeto SceneAnalyzedEventArgs passado para o manipulador tem um objeto SceneAnalysisEffectFrame que possui um objeto HighDynamicRangeOutput. A propriedade Certainty da saída de HDR fornece um valor entre 0 e 1,0, onde 0 indica que o processamento em HDR não ajudaria a melhorar o resultado da captura e 1,0 indica que o processamento em HDR ajudaria. Você pode decidir o ponto de limite no qual deseja usar HDR ou mostrar os resultados ao usuário e permitir que ele 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.");
    }
}

O objeto HighDynamicRangeOutput passado para o manipulador também tem uma propriedade FrameControllers, que contém controladores de quadro sugeridos para capturar uma sequência de fotos variável para processamento em HDR. Para obter mais informações, consulte Sequência de fotos variável.

Limpar o efeito da análise de cena

Quando seu aplicativo terminar a captura, antes de descartar o objeto MediaCapture, você deve desabilitar o efeito de análise de cena definindo a propriedade HighDynamicRangeAnalyzer.Enabled do efeito como false e cancelar o registro de seu manipulador de eventos SceneAnalyzed. Chame MediaCapture.ClearEffectsAsync especificando o fluxo de visualização de vídeo, desde que tenha sido o fluxo ao qual o efeito foi adicionado. Por fim, defina a variável de membro como nula.

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

Efeito de detecção de rosto

O FaceDetectionEffect identifica a localização de rostos dentro do fluxo de visualização da captura de mídia. O efeito permite que você receba uma notificação sempre que um rosto for detectado no fluxo de visualização e fornece a caixa delimitadora para cada rosto detectado dentro do quadro de visualização. Em dispositivos com suporte, o efeito de detecção de rosto também fornece exposição avançada e foco no rosto mais importante na cena.

Namespaces de detecção de rosto

Para usar a detecção de rosto, seu aplicativo deve incluir os namespaces a seguir, além dos namespaces necessários para a captura de mídia básica.

using Windows.Media.Core;

Inicializar o efeito de detecção de rosto e adicioná-lo ao fluxo de visualização

Os efeitos de vídeo são implementados usando-se duas APIs, uma definição de efeito, que fornece as configurações que o dispositivo de captura precisa para inicializar o efeito, e uma instância de efeito, que pode ser usada para controlar o efeito. Como você pode querer acessar a instância de efeito de vários locais dentro do seu código, normalmente você deve declarar uma variável de membro para manter o objeto.

FaceDetectionEffect _faceDetectionEffect;

No seu aplicativo, depois de você ter inicializado o objeto MediaCapture, crie uma nova instância de FaceDetectionEffectDefinition. Defina a propriedade DetectionMode para priorizar a detecção de rosto mais rápida ou a mais precisa. Defina SynchronousDetectionEnabled para especificar que os quadros recebidos não atrasem aguardando a detecção de rosto ser concluída, já que isso pode resultar em uma experiência de visualização truncada.

Registre o efeito com o dispositivo de captura chamando AddVideoEffectAsync no seu objeto MediaCapture, fornecendo FaceDetectionEffectDefinition e especificando MediaStreamType.VideoPreview para indicar que o efeito deve ser aplicado ao fluxo de visualização de vídeo, em vez do fluxo de captura. AddVideoEffectAsync retorna uma instância do efeito adicionado. Como esse método pode ser usado com vários tipos de efeito, você deve converter a instância retornada em um objeto FaceDetectionEffect.

Habilite ou desabilite os efeitos definindo a propriedade FaceDetectionEffect.Enabled. Ajuste quantas vezes o efeito analisa os quadros definindo a propriedade FaceDetectionEffect.DesiredDetectionInterval. Ambas as propriedades podem ser ajustadas enquanto captura de mídia está em andamento.


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

Receber notificações quando os rostos forem detectados

Se você deseja executar algumas ações quando rostos forem detectados, como desenhar uma caixa ao redor dos rostos detectados na visualização de vídeo, você pode registrar o evento FaceDetected.

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

No manipulador do evento, você pode obter uma lista de todos os rostos detectados em um quadro acessando a propriedade FaceDetectionEffectFrame.DetectedFaces do FaceDetectedEventArgs. A propriedade FaceBox é uma estrutura BitmapBounds que descreve o retângulo contendo o rosto detectado em unidades relativas às dimensões do fluxo de visualização. Para ver o código de amostra que transforma as coordenadas do fluxo de visualização em coordenadas de tela, consulte o amostra UWP de detecção de rosto.

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

Limpar o efeito de detecção de rosto

Quando seu aplicativo terminar a captura, antes de descartar o objeto MediaCapture, você deve desabilitar o efeito de detecção de rosto com FaceDetectionEffect.Enabled e cancelar o registro do seu manipulador de eventos FaceDetected se tiver registrado um anteriormente. Chame MediaCapture.ClearEffectsAsync especificando o fluxo de visualização de vídeo, desde que tenha sido o fluxo ao qual o efeito foi adicionado. Por fim, defina a variável de membro como nula.

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

Verificar se há suporte para foco e exposição para os rostos detectados

Nem todos os dispositivos têm um mecanismo de captura que possa ajustar o foco e a exposição com base nos rostos detectados. Como a detecção de rosto consome recursos do dispositivo, você pode querer apenas ativar a detecção de rosto em dispositivos que possam usar o recurso para aprimorar a captura. Para ver se a otimização de captura com base no rosto está disponível, obtenha o VideoDeviceController para sua MediaCapture inicializada e baixe o RegionsOfInterestControl do controlador de dispositivo de vídeo. Verifique se o MaxRegions dá suporte a pelo menos uma região. Em seguida, verifique se AutoExposureSupported ou AutoFocusSupported estão definidas como true. Se essas condições forem atendidas, o dispositivo poderá aproveitar a detecção de rosto para melhorar a captura.

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