ビデオ キャプチャのための手動カメラ制御

この記事では、ビデオ キャプチャの拡張シナリオ (HDR ビデオ、露出の優先順位など) を手動デバイス制御によって有効にする方法を示します。

この記事で説明するビデオ デバイス コントロールはすべて同じパターンを使ってアプリに追加されます。 まず、アプリが実行されている現在のデバイスで、コントロールがサポートされているかどうかを確認します。 コントロールがサポートされている場合は、コントロールに対して必要なモードを設定します。 一般的に、現在のデバイスで特定のコントロールがサポートされていない場合は、ユーザーがその機能を有効にできるような UI 要素を無効または非表示にする必要があります。

この記事で説明するデバイス制御 API はすべて、Windows.Media.Devices 名前空間のメンバーです。

using Windows.Media.Devices;

注意

この記事の内容は、写真やビデオの基本的なキャプチャ機能を実装するための手順を紹介した「MediaCapture を使った基本的な写真、ビデオ、およびオーディオのキャプチャ」で取り上げた概念やコードに基づいています。 そちらの記事で基本的なメディア キャプチャのパターンを把握してから、高度なキャプチャ シナリオに進むことをお勧めします。 この記事で紹介しているコードは、MediaCapture のインスタンスが既に作成され、適切に初期化されていることを前提としています。

HDR ビデオ

ハイ ダイナミック レンジ (HDR) ビデオ機能では、HDR 処理をキャプチャ デバイスのビデオ ストリームに適用します。 HDR ビデオがサポートされているかどうかを確認するには、HdrVideoControl.Supported プロパティを選びます。

HDR ビデオ コントロールでは、3 つのモード (オン、オフ、自動) がサポートされています。自動モードでは、HDR ビデオ処理によってメディア キャプチャが改善されるかどうかをデバイスが動的に判断し、改善される場合は HDR ビデオが有効になります。 現在のデバイスで特定のモードがサポートされているかどうかを確認するには、HdrVideoControl.SupportedModes コレクションに目的のモードが含まれているかどうかをチェックします。

HDR ビデオ処理を有効または無効にするには、HdrVideoControl.Mode を目的のモードに設定します。 このコントロールでは、モードが設定される前にストリームが停止状態になっている必要があります。「KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOHDR」を参照してください。

private void SetHdrVideoMode(HdrVideoMode mode)
{
    if (!_mediaCapture.VideoDeviceController.HdrVideoControl.Supported)
    {
        ShowMessageToUser("HDR Video not available");
        return;
    }

    var hdrVideoModes = _mediaCapture.VideoDeviceController.HdrVideoControl.SupportedModes;

    if (!hdrVideoModes.Contains(mode))
    {
        ShowMessageToUser("HDR Video setting not supported");
        return;
    }

    _mediaCapture.VideoDeviceController.HdrVideoControl.Mode = mode;
}

露出の優先順位

ExposurePriorityVideoControl は、有効であれば、キャプチャ デバイスからのビデオ フレームを評価し、ローライト シーンのビデオがキャプチャされているかどうかを判断します。 その場合は、各フレームの露出時間を長くし、キャプチャしたビデオの画質を向上するために、キャプチャするビデオのフレーム レートが引き下げられます。

ExposurePriorityVideoControl.Supported プロパティをチェックして、現在のデバイスで露出の優先順位コントロールがサポートされているかどうかを確認してください。

露出の優先順位コントロールを有効または無効にするには、ExposurePriorityVideoControl.Enabled を目的のモードに設定します。

if (!_mediaCapture.VideoDeviceController.ExposurePriorityVideoControl.Supported)
{
    ShowMessageToUser("Exposure priority not available");
    return;
}
_mediaCapture.VideoDeviceController.ExposurePriorityVideoControl.Enabled = true;

一時的なノイズ除去

Windows 10、バージョン 1803 以降では、デバイスでサポートされている場合、そのデバイスのビデオに対して一時的なノイズ除去を有効できます。 この機能では、隣接する複数のフレームの画像データがリアル タイムで融合されて、画像ノイズの少ないビデオ フレームが生成されます。

アプリは、VideoTemporalDenoisingControl によって、一時的なノイズ除去が現在のデバイスでサポートされているかどうか、またサポートされている場合は、サポートされている一時的なノイズ除去のモードを判定します。 利用可能な一時的なノイズ除去モードは、OffOnAuto です。デバイスはすべてのモードをサポートする必要はありませんが、すべてのデバイスは、Auto または OnOff をサポートする必要があります。

次の例では、シンプルな UI を使用して、ユーザーが一時的なノイズ除去の複数モードを切り替えられるラジオ ボタンを配置します。

<StackPanel Orientation="Vertical" HorizontalAlignment="Right" >
    <StackPanel x:Name="denoiseControls" Visibility="Collapsed">
        <TextBlock>Temporal Denoising</TextBlock>
        <RadioButton x:Name="denoiseOffButton" Checked="denoiseButton_Checked"
    GroupName="Denoise Group" Content="Off"/>
        <RadioButton x:Name="denoiseOnButton" Checked="denoiseButton_Checked"
    GroupName="Denoise Group" Content="On" Visibility="Collapsed"/>
        <RadioButton x:Name="denoiseAutoButton" Checked="denoiseButton_Checked"
    GroupName="Denoise Group" Content="Auto" Visibility="Collapsed"/>
    </StackPanel>
</StackPanel>

次のメソッドでは、VideoTemporalDenoisingControl.Supported プロパティを確認し、現在のデバイスで一時的なノイズ除去がサポートされているかどうかをまず判断します。 サポートされている場合は、さらに Off および AutoOn がサポートされていることを確認し、サポートされていればラジオボタンを表示します。 次に AutoOn のボタンのメソッドがサポートされている場合は、それらのボタンを表示します。

private void UpdateDenoiseCapabilities()
{
    if (_mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Supported)
    {
         IReadOnlyList<VideoTemporalDenoisingMode> modes = _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.SupportedModes;
        if(modes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.Off) &&
           (modes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.On) || 
           modes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.Auto)))
        {
            denoiseControls.Visibility = Visibility.Visible;

            if (modes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.On))
            {
                denoiseOnButton.Visibility = Visibility.Visible;
            }
            if (modes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.Auto))
            {
                denoiseAutoButton.Visibility = Visibility.Visible;
            }
        }
    }
}

ラジオ ボタンの Checked イベント ハンドラーで、ボタン名を確認し、VideoTemporalDenoisingControl.Mode プロパティを設定して、対応するモードを設定します。

private void denoiseButton_Checked(object sender, RoutedEventArgs e)
{
    var button = sender as RadioButton;
    if(button.Name == "denoiseOffButton")
    {
        _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Mode = Windows.Media.Devices.VideoTemporalDenoisingMode.Off;
    }
    else if (button.Name == "denoiseOnButton")
    {
        _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Mode = Windows.Media.Devices.VideoTemporalDenoisingMode.On;
    }
    else if (button.Name == "denoiseAutoButton")
    {
        _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Mode = Windows.Media.Devices.VideoTemporalDenoisingMode.Auto;
    }
}

フレームの処理中に一時的なノイズ除去を無効にする

一時的なノイズ除去を使用して処理されたビデオは、人間の目にはより快適です。 しかし一時的なノイズ除去は画像の一貫性に影響を及ぼし、フレーム内の詳細さが低下するため、登録や OCR など、フレーム内の画像処理を行うアプリでは、画像処理を有効にする間、プログラムによる一時的なノイズ除去の無効化が必要になることがあります。

次の例では、サポートされているノイズ除去モードを判断し、この情報をいくつかのクラス変数に格納します。

private bool _isVideoTemporalDenoisingOffSupported = false;
private bool _isProcessing = false;
private Windows.Media.Devices.VideoTemporalDenoisingMode? _videoDenoisingEnabledMode = null;
private void ConfigureDenoiseForFrameProcessing()
{
    if (_mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Supported)
    {
        // Query support for the VideoTemporalDenoising control Off mode
        _isVideoTemporalDenoisingOffSupported = _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.SupportedModes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.Off);

        // Query support for a mode that would enable VideoTemporalDenoising (On or Auto) and toggle it if supported
        if (_mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.SupportedModes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.On))
        {
            _videoDenoisingEnabledMode = Windows.Media.Devices.VideoTemporalDenoisingMode.On;
            _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Mode = (Windows.Media.Devices.VideoTemporalDenoisingMode)_videoDenoisingEnabledMode;
        }
        else if (_mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.SupportedModes.Contains(Windows.Media.Devices.VideoTemporalDenoisingMode.Auto))
        {
            _videoDenoisingEnabledMode = Windows.Media.Devices.VideoTemporalDenoisingMode.Auto;
            _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Mode = (Windows.Media.Devices.VideoTemporalDenoisingMode)_videoDenoisingEnabledMode;
        }
    }

}

アプリはフレーム処理を有効にするとき、そのモードがサポートされている場合は、ノイズ除去機能を Off に設定します。これにより、フレーム処理がノイズ除去されない未加工のフレームを使用できるようになります。

public void EnableFrameProcessing()
{
    // Toggle Off VideoTemporalDenoising
    if (_isVideoTemporalDenoisingOffSupported)
    {
        _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Mode = Windows.Media.Devices.VideoTemporalDenoisingMode.Off;
    }

    _isProcessing = true;
}

アプリはフレーム処理を無効にするとき、サポートされているモードに応じて、ノイズ除去モードを On または Auto に設定します。

public void DisableFrameProcessing()
{
    _isProcessing = false;

    // If a VideoTemporalDenoising mode to enable VideoTemporalDenoising is supported, toggle it
    if (_videoDenoisingEnabledMode != null)
    {
        _mediaCapture.VideoDeviceController.VideoTemporalDenoisingControl.Mode = (Windows.Media.Devices.VideoTemporalDenoisingMode)_videoDenoisingEnabledMode;
    }
}

画像処理用にビデオ フレームを取得する方法について詳しくは、「MediaFrameReader を使ったメディア フレームの処理」をご覧ください。