Efeitos para analisar quadros de câmera

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

Efeito de análise de cena

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 se a captura seria aprimorada usando o processamento HDR (High Dynamic Range).

Se o efeito recomendar o uso de HDR, você poderá 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;

Inicialize o efeito de análise de cena e adicione-o 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 você pode querer acessar a instância de efeito de vários locais dentro do código, normalmente deve declarar uma variável de membro para manter o objeto.

private SceneAnalysisEffect _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 o 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 alta faixa dinâmica. Habilite a análise HDR definindo HighDynamicRangeControl.Enabled do efeito 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 tem um objeto HighDynamicRangeOutput. A propriedade Certainty da saída de alta faixa dinâmica fornece um valor entre 0 e 1,0, em que 0 indica que o processamento HDR não ajudaria a melhorar o resultado da captura e 1,0 indica que o processamento HDR ajudaria. Você pode decidir o ponto limite no qual deseja usar o HDR ou mostrar os resultados ao usuário e deixar 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)
    {
        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 HDR. Para obter mais informações, consulte Sequência de fotos variável.

Limpe 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, pois esse foi o fluxo ao qual o efeito foi adicionado. Por fim, defina sua 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 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 uma face for detectada no fluxo de visualização e fornece a caixa delimitadora para cada face detectada dentro do quadro de visualização. Em dispositivos compatíveis, o efeito de detecção de rosto também fornece exposição aprimorada e foco no rosto mais importante da cena.

Namespaces de detecção facial

Para usar a detecção facial, 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;

Inicialize o efeito de detecção de rosto e adicione-o 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 você pode querer acessar a instância de efeito de vários locais dentro do código, normalmente deve declarar uma variável de membro para manter o objeto.

FaceDetectionEffect _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 quadros de entrada não sejam atrasados aguardando a conclusão da detecção facial, pois 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 o 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 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
_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;

Receba notificações quando forem detetados rostos

Se você quiser executar alguma ação quando rostos forem detectados, como desenhar uma caixa ao redor dos rostos detectados na visualização do vídeo, poderá se registrar para 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 que contém a face detectada em unidades relativas às dimensões do fluxo de visualização. Para exibir o código de exemplo que transforma as coordenadas do fluxo de visualização em coordenadas de tela, consulte o exemplo 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
    }
}

Limpe o efeito de detecção de rosto

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ê tiver registrado um anteriormente. Chame MediaCapture.ClearEffectsAsync, especificando o fluxo de visualização de vídeo, pois esse foi o fluxo ao qual o efeito foi adicionado. Por fim, defina sua 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;

Verifique o 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 nos rostos detectados. Como a detecção facial consome recursos do dispositivo, talvez você queira habilitar a detecção facial apenas em dispositivos que podem usar o recurso para aprimorar a captura. Para ver se a otimização de captura baseada em rosto está disponível, obtenha o VideoDeviceController para o MediaCapture inicializado e, em seguida, obtenha 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 são verdadeiros. Se essas condições forem atendidas, o dispositivo poderá aproveitar a detecção facial para aprimorar a captura.

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