Análise de cena para MediaCapture

Este artigo descreve como usar o SceneAnalysisEffect e o FaceDetectionEffect para analisar o conteúdo do fluxo de pré-visualização da captura de media.

Efeito da análise de cena

O SceneAnalysisEffect analisa os frames de vídeo no fluxo de pré-visualização da captura de media e recomenda opções de processamento para melhorar o resultado da captura. Atualmente, o efeito suporta a deteção se a captura seria melhorada usando processamento de Alta Gama Dinâmica (HDR).

Se o efeito recomendar o uso de HDR, pode fazê-lo das seguintes formas:

Inicialize o efeito de análise de cena e adicione-o ao stream de pré-visualização

Os efeitos de vídeo são implementados usando duas APIs: uma definição de efeito, que fornece as definições necessárias ao dispositivo de captura para inicializar o efeito, e uma instância de efeito, que pode ser usada para controlar o efeito. Como pode querer aceder à instância de efeito a partir de vários locais dentro do seu código, normalmente deve declarar uma variável membro para armazenar o objeto.

private SceneAnalysisEffect m_sceneAnalysisEffect;

Na sua aplicação, depois de inicializar o objeto MediaCapture , crie uma nova instância de SceneAnalysisEffectDefinition.

Regista o efeito com o dispositivo de captura chamando AddVideoEffectAsync no teu objeto MediaCapture , fornecendo o SceneAnalysisEffectDefinition e especificando MediaStreamType.VideoPreview para indicar que o efeito deve ser aplicado ao fluxo de pré-visualização de vídeo, em vez do fluxo de captura. AddVideoEffectAsync devolve uma instância do efeito adicionado. Como este método pode ser usado com múltiplos tipos de efeito, deve castar a instância devolvida para um objeto SceneAnalysisEffect .

Para receber os resultados da análise da cena, deve registar um handler para o evento SceneAnalysed .

Atualmente, o efeito de análise de cena inclui apenas o analisador de alto alcance dinâmico. Ative a análise HDR definindo o 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;

Implemente o gestor de eventos SceneAnalyzed

Os resultados da análise da cena são devolvidos no handler de eventos SceneAnalyzed. O objeto SceneAnalyzedEventArgs passado no handler tem um objeto SceneAnalysisEffectFrame que possui um objeto HighDynamicRangeOutput . A propriedade de Certeza da saída de alta gama dinâmica fornece um valor entre 0 e 1.0, onde 0 indica que o processamento HDR não ajudaria a melhorar o resultado da captura e 1.0 indica que o processamento HDR ajudaria. Podes decidir o ponto limite em que queres usar HDR ou mostrar os resultados ao utilizador e deixar que o utilizador 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 handler também tem uma propriedade FrameControllers que contém controladores de frames sugeridos para capturar uma sequência fotográfica variável para processamento HDR. Para mais informações, veja Sequência fotográfica variável.

Limpar o efeito da análise da cena

Quando a sua aplicação terminar de capturar, antes de descartar o objeto MediaCapture, deve desativar o efeito de análise de cena definindo a propriedade HighDynamicRangeAnalyzer.Enabled para False e desinscrever o seu manipulador de eventos SceneAnalyzed. Chame MediaCapture.ClearEffectsAsync, especificando o stream de pré-visualização de vídeo, já que foi esse o stream ao qual o efeito foi adicionado. Por fim, define a variável 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 deteção facial

O FaceDetectionEffect identifica a localização dos rostos dentro do fluxo de pré-visualização da captura de media. O efeito permite receber uma notificação sempre que uma cara é detetada no fluxo de pré-visualização e fornece a caixa delimitadora para cada face detetada dentro do frame de pré-visualização. Nos dispositivos suportados, o efeito de deteção facial também proporciona exposição e foco melhorados no rosto mais importante da cena.

Inicialize o efeito de deteção facial e adicione-o ao stream de pré-visualização

Os efeitos de vídeo são implementados usando duas APIs: uma definição de efeito, que fornece as definições necessárias ao dispositivo de captura para inicializar o efeito, e uma instância de efeito, que pode ser usada para controlar o efeito. Como pode querer aceder à instância de efeito a partir de vários locais dentro do seu código, normalmente deve declarar uma variável membro para armazenar o objeto.

FaceDetectionEffect m_faceDetectionEffect;

Na sua aplicação, depois de inicializar o objeto MediaCapture , crie uma nova instância de FaceDetectionEffectDefinition. Defina a propriedade DetectionMode para priorizar uma deteção facial mais rápida ou mais precisa. Defina SynchronousDetectionEnabled para especificar que os frames recebidos não estão atrasados à espera que a deteção facial seja concluída, pois isso pode resultar numa experiência de pré-visualização irregular.

Regista o efeito com o dispositivo de captura chamando AddVideoEffectAsync no teu objeto MediaCapture , fornecendo o FaceDetectionEffectDefinition e especificando MediaStreamType.VideoPreview para indicar que o efeito deve ser aplicado ao fluxo de pré-visualização de vídeo, em vez do fluxo de captura. AddVideoEffectAsync devolve uma instância do efeito adicionado. Como este método pode ser usado com vários tipos de efeito, deve castar a instância devolvida para um objeto FaceDetectionEffect .

Ative ou desative o efeito definindo a propriedade FaceDetectionEffect.Enabled . Ajuste a frequência com que o efeito analisa os frames definindo a propriedade FaceDetectionEffect.DesiredDetectionInterval . Ambas as propriedades podem ser ajustadas enquanto a captura de media está em 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
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;

Receba notificações quando são detetadas faces

Se quiseres realizar alguma ação quando as faces são detetadas, como desenhar uma caixa à volta das faces detetadas na pré-visualização do vídeo, podes inscrever-te no evento FaceDetected .

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

No handler do evento, pode obter uma lista de todas as faces detetadas num frame acedendo à propriedade FaceDetectionEffectFrame.DetectedFaces dos FaceDetectedEventArgs. A propriedade FaceBox é uma estrutura BitmapBounds que descreve o retângulo que contém a face detetada em unidades relativas às dimensões do fluxo de pré-visualização. Para ver código de exemplo que transforma as coordenadas do fluxo de pré-visualização em coordenadas de ecrã, consulte o exemplo UWP de deteção de rostos.

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 deteção facial

Quando a sua aplicação terminar de capturar, antes de descartar o objeto MediaCapture, deve desativar o efeito de deteção facial com FaceDetectionEffect.Desativado e retirar o seu gestor de eventos FaceDetected, caso já o tenha registado. Chame MediaCapture.ClearEffectsAsync, especificando o stream de pré-visualização de vídeo, já que foi esse o stream ao qual o efeito foi adicionado. Por fim, define a variável 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;

Verifique o suporte de foco e exposição para rostos detetados

Nem todos os dispositivos têm um dispositivo de captura que possa ajustar o seu foco e exposição com base nas faces detetadas. Como a deteção facial consome recursos do dispositivo, pode querer ativar apenas a deteção facial em dispositivos que possam usar a funcionalidade para melhorar a captura. Para verificar se está disponível a otimização de captura baseada em face, obtenha o VideoDeviceController para o seu MediaCapture já inicializado e, em seguida, o RegionsOfInterestControl do controlador de dispositivo de vídeo. Verifica se o MaxRegions suporta pelo menos uma região. Depois verifica se AutoExposureSupported ou AutoFocusSupported são os verdadeiros. Se estas condições forem cumpridas, o dispositivo pode aproveitar a deteção facial para melhorar a captura.

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