共用方式為


分析相機畫面的效果

本文說明如何使用 SceneAnalysisEffectFaceDetectionEffect 來分析媒體擷取預覽串流的內容。

場景分析效果

SceneAnalysisEffect 會分析媒體擷取預覽串流中的視訊畫面,並建議處理選項以改善擷取結果。 目前,效果支援使用高動態範圍 (HDR) 處理來偵測擷取是否會改善。

如果效果建議使用 HDR,您可以透過下列方式執行此動作:

場景分析命名空間

若要使用場景分析,除了基本媒體擷取所需的命名空間之外,您的應用程式還必須包含下列命名空間。

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

初始化場景分析效果,並將其新增至預覽串流

視訊效果是使用兩個 API 來實作,也就是效果定義,其提供擷取裝置需要初始化效果的設定,以及可用來控制效果的效果效果的效果執行個體。 由於您可能想要從程式碼內的多個位置存取效果執行個體,因此您通常應該宣告成員變數來保存物件。

private SceneAnalysisEffect _sceneAnalysisEffect;

在應用程式中,初始化 MediaCapture 使用者之後,請建立 SceneAnalysisEffectDefinition 的新執行個體。

MediaCapture 物件上呼叫 AddVideoEffectAsync,提供 SceneAnalysisEffectDefinition 並指定 MediaStreamType.VideoPreview,以向擷取裝置註冊效果,以指出效果應該套用至視訊預覽串流,而不是擷取串流。 AddVideoEffectAsync 會傳回新增效果的執行個體。 由於這個方法可以搭配多個效果類型使用,因此您必須將傳回的執行個體轉換成 SceneAnalysisEffect 物件。

若要接收場景分析的結果,您必須註冊 SceneAnalyzed 事件的處理常式。

目前,場景分析效果只包含高動態範圍分析器。 將效果的 HighDynamicRangeControl.Enabled 設定為 true,以啟用 HDR 分析。

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

實作 SceneAnalyzed 事件處理常式

場景分析的結果會在 SceneAnalyzed 事件處理常式中傳回。 傳遞至處理常式的 SceneAnalyzedEventArgs 物件具有 SceneAnalysisEffectFrame 物件,其具有 HighDynamicRangeOutput 物件。 高動態範圍輸出的 Certainty 屬性提供介於 0 到 1.0 之間的值,其中 0 表示 HDR 處理無法協助改善擷取結果,1.0 表示 HDR 處理會有所説明。 您可以決定您想要使用 HDR 的臨界點,或向使用者顯示結果,並讓用戶決定。

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.");
    }
}

傳入處理常式的 HighDynamicRangeOutput 物件也有 FrameControllers 屬性,其中包含用於擷取可變相片序列以進行 HDR 處理的建議畫面控制器。 有關詳細資訊,請參閱可變相片序列

清除場景分析效果

當您的應用程式完成擷取之前,在處置 MediaCapture 物件之前,您應該將效果的 HighDynamicRangeAnalyzer.Enabled 屬性設定為 false 並取消註冊 SceneAnalyzed 事件處理常式,以停用場景分析效果。 呼叫 MediaCapture.ClearEffectsAsync,指定影片預覽串流,因為這是新增效果的串流。 最後,將您的成員變數設定為 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;

臉部偵測效果

FaceDetectionEffect 會識別媒體擷取預覽串流中臉部的位置。 效果可讓您在預覽串流中偵測到臉部時收到通知,並提供預覽畫面內每個偵測到臉部的周框方塊。 在支援的裝置上,臉部偵測效果也會提供增強的曝光度,並將焦點放在場景中最重要的臉部。

臉部偵測命名空間

若要使用臉部偵測,除了基本媒體擷取所需的命名空間之外,您的應用程式還必須包含下列命名空間。

using Windows.Media.Core;

初始化臉部偵測效果,並將其新增至預覽串流

視訊效果是使用兩個 API 來實作,也就是效果定義,其提供擷取裝置需要初始化效果的設定,以及可用來控制效果的效果效果的效果執行個體。 由於您可能想要從程式碼內的多個位置存取效果執行個體,因此您通常應該宣告成員變數來保存物件。

FaceDetectionEffect _faceDetectionEffect;

在應用程式中,初始化 MediaCapture 物件之後,請建立 FaceDetectionEffectDefinition 的新執行個體。 設定 DetectionMode 屬性,以設定更快速的臉部偵測或更精確的臉部偵測優先順序。 設定 SynchronousDetectionEnabled 以指定傳入畫面不會延遲等待臉部偵測完成,因為這可能會造成不穩定的預覽體驗。

MediaCapture 物件上呼叫 AddVideoEffectAsync,提供 SceneAnalysisEffectDefinition 並指定 MediaStreamType.VideoPreview,以向擷取裝置註冊效果,以指出效果應該套用至視訊預覽串流,而不是擷取串流。 AddVideoEffectAsync 會傳回新增效果的執行個體。 由於這個方法可以搭配多個效果類型使用,因此您必須將傳回的執行個體轉換成 FaceDetectionEffect 物件。

藉由設定 FaceDetectionEffect.Enabled 屬性來啟用或停用效果。 藉由設定 FaceDetectionEffect.DesiredDetectionInterval 屬性來調整效果分析畫面的頻率。 這兩個屬性都可以在媒體擷取進行時進行調整。


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

偵測到臉部時接收通知

如果您想要在偵測到臉部時執行一些動作,例如在影片預覽中繪製偵測到臉部周圍的方塊,您可以註冊 FaceDetected 事件。

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

在事件的處理常式中,您可以存取 FaceDetectedEventArgsFaceDetectionEffectFrame.DetectedFaces 屬性,以取得畫面中偵測到的所有臉部清單。 FaceBox 屬性是 BitmapBounds 結構,描述相對於預覽串流維度的單位包含偵測到臉部的矩形。 若要檢視將預覽串流座標轉換成螢幕座標的範例程式碼,請參閱臉部偵測 UWP 範例

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

清除臉部偵測效果

當您的應用程式完成擷取之前,處置 MediaCapture 物件之前,您應該停用 FaceDetectionEffect.Enabled 的臉部偵測效果,並在您先前註冊 FaceDetected 事件處理常式時取消註冊。 呼叫 MediaCapture.ClearEffectsAsync,指定影片預覽串流,因為這是新增效果的串流。 最後,將您的成員變數設定為 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;

檢查偵測到臉部的焦點和曝光支援

並非所有裝置都有擷取裝置,可根據偵測到的臉部來調整其焦點和曝光。 由於臉部偵測會耗用裝置資源,因此您可能只想要在可使用此功能來增強擷取功能的裝置上啟用臉部偵測。 若要查看臉部型擷取最佳化是否可用,請取得已初始化 MediaCaptureVideoDeviceController,然後取得視訊裝置控制器的 RegionsOfInterestControl。 檢查 MaxRegions 是否支援至少一個區域。 然後檢查 AutoExposureSupportedAutoFocusSupported 是否為 true。 如果符合這些條件,則裝置可以利用臉部偵測來增強擷取。

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