Análise de cena para MediaCapture

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 cenas

O 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 dá suporte à detecção de se a captura seria aprimorada usando o processamento de HDR (Alto Intervalo Dinâmico).

Se o efeito recomendar o uso do HDR, você poderá fazer isso das seguintes maneiras:

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

Os efeitos de vídeo são implementados usando duas APIs, uma definição de efeito, que fornece 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 talvez você queira acessar a instância de efeito de vários locais dentro do código, normalmente você deve declarar uma variável de membro para manter o objeto.

private SceneAnalysisEffect m_sceneAnalysisEffect;

Em seu aplicativo, depois de inicializar o objeto MediaCapture , crie uma nova instância de SceneAnalysisEffectDefinition.

Registre o efeito com o dispositivo de captura chamando AddVideoEffectAsync em 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 apenas o analisador de intervalo dinâmico alto. Ative a análise HDR definindo a propriedade HighDynamicRangeControl.Enabled do efeito como true.

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

// Add the effect to the video preview stream
m_sceneAnalysisEffect = (SceneAnalysisEffect)await m_mediaCapture.AddVideoEffectAsync(definition, MediaStreamType.VideoPreview);

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

// Enable HDR analysis
m_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 tem um objeto HighDynamicRangeOutput . A propriedade Certainty da saída de alto intervalo dinâmico fornece um valor entre 0 e 1,0, em que 0 indica que o processamento de HDR não ajudaria a melhorar o resultado da captura e 1.0 indica que o processamento do HDR ajudaria. Você pode decidir o ponto limite no qual deseja usar o HDR ou mostrar os resultados para o usuário e permitir que o usuário 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)
    {
        DispatcherQueue.TryEnqueue(() =>
        {
            tbStatus.Text = "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 hdr. Para obter mais informações, consulte a sequência de fotos variável.

Remover o efeito de análise de cena

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

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

m_sceneAnalysisEffect.SceneAnalyzed -= SceneAnalysisEffect_SceneAnalyzed;

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

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

Efeito de detecção facial

O FaceDetectionEffect identifica o local dos rostos no fluxo de visualização de 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 facial também fornece maior exposição e foco no rosto mais importante da cena.

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

Os efeitos de vídeo são implementados usando duas APIs, uma definição de efeito, que fornece 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 talvez você queira acessar a instância de efeito de vários locais dentro do código, normalmente você deve declarar uma variável de membro para manter o objeto.

FaceDetectionEffect m_faceDetectionEffect;

Em seu aplicativo, depois de inicializar o objeto MediaCapture , crie uma nova instância de FaceDetectionEffectDefinition. Defina a propriedade DetectionMode para priorizar a detecção facial mais rápida ou a detecção facial mais precisa. Defina SynchronousDetectionEnabled para especificar que os frames de entrada não estão atrasados aguardando a conclusão da detecção facial, uma vez que isso pode resultar em uma experiência de visualização instável.

Registre o efeito com o dispositivo de captura chamando AddVideoEffectAsync em 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 o efeito definindo a propriedade FaceDetectionEffect.Enabled . Ajuste a frequência com que o efeito analisa os quadros definindo a propriedade FaceDetectionEffect.DesiredDetectionInterval . Ambas as propriedades podem ser ajustadas enquanto a 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
m_faceDetectionEffect = (FaceDetectionEffect)await m_mediaCapture.AddVideoEffectAsync(definition, MediaStreamType.VideoPreview);

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

// Start detecting faces
m_faceDetectionEffect.Enabled = true;

Receber notificações quando rostos são detectados

Se você quiser executar alguma ação quando forem detectados rostos, como desenhar uma caixa em torno de rostos detectados na visualização de vídeo, você poderá se registrar para o evento FaceDetected .

// Register for face detection events
m_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 que contém o rosto detectado em unidades relativas às dimensões de fluxo de visualização. Para exibir o código de exemplo que transforma as coordenadas de fluxo de visualização em coordenadas de tela, consulte o exemplo de UWP de detecção facial.

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 facial

Quando o aplicativo terminar de capturar, antes de descartar o objeto MediaCapture , você deverá desabilitar o efeito de detecção facial com FaceDetectionEffect.Enabled e cancelar o registro do manipulador de eventos FaceDetected se você registrou anteriormente um. Chame MediaCapture.ClearEffectsAsync, especificando o fluxo de visualização de vídeo, porque esse foi o fluxo ao qual o efeito foi adicionado. Por fim, defina a variável de membro como nula.

// Disable detection
m_faceDetectionEffect.Enabled = false;

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

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

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

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

Nem todos os dispositivos têm um dispositivo de captura que pode ajustar seu foco e exposição com base em rostos detectados. Como a detecção facial consome recursos do dispositivo, talvez você queira habilitar apenas a detecção facial em dispositivos que podem usar o recurso para aprimorar a captura. Para verificar se a otimização de captura baseada em rosto está disponível, primeiro obtenha o VideoDeviceController para o seu MediaCapture inicializado e, em seguida, acesse o RegionsOfInterestControl do controlador de dispositivo de vídeo. Verifique se as MaxRegions dão suporte a pelo menos uma região. Em seguida, verifique se AutoExposureSupported ou AutoFocusSupported são verdadeiros. Se essas condições forem atendidas, o dispositivo poderá aproveitar a detecção facial para aprimorar a captura.

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