
-
機械学習にもとづくビデオエフェクトでアプリを強化
フレームレート変換、超高解像度、ノイズフィルタなどのエフェクトを追加して、ビデオ編集やライブストリーミングの体験を向上させる方法を学びましょう。Video Toolboxフレームワークに搭載され、Appleシリコン向けに最適化された機械学習にもとづくビデオ処理アルゴリズムについて詳しく説明します。これらのエフェクトを統合し、実際のユースケースで利用できるようにアプリの機能を向上させる方法について解説します。
関連する章
- 0:00 - イントロダクション
- 1:04 - ビデオエフェクトの概要
- 4:55 - アプリへのエフェクトの追加
- 6:46 - 使用例:フレームレート変換
- 11:16 - 使用例:被写体ぶれエフェクト
- 13:46 - 使用例:低遅延/超高解像度エフェクト
- 14:55 - 使用例:低遅延フレーム補間
リソース
-
このビデオを検索
こんにちは Video Processingチーム エンジニアのMakhloufです Video Toolboxは ビデオアプリで最も 使用されているフレームワークの1つです 様々なビデオのニーズに対応できるように 豊富な機能を備えています macOS 15.4以降 Appleシリコンに最適化した MLベースのビデオ処理アルゴリズムの VTFrameProcessor APIによって 強化されましたが うれしいことに このAPIを iOS 26でも利用できるようになりました このビデオでは最初にVTFrameProcessor APIにより利用可能になった エフェクトについて説明した後 エフェクトをアプリに統合する 基本的な手順について見ていきます 最後に よくあるいくつかのユースケースを例として 実際に実装してみます VTFrameProcessor APIには多用途に 対応する様々なエフェクトがあります フレームレート変換や 超高解像度 被写体ぶれなどのエフェクトは 高品質のビデオ編集用に 設計されています 低遅延のフレーム補間や 超高解像度エフェクトは リアルタイムに処理する必要がある アプリに向いています テンポラルノイズフィルタは そのどちらの場合も使用できます これらのエフェクトを使用して どのようなことができるか見てみましょう フレームレート変換では クリップの1秒あたりのフレーム数を ターゲットのFPSに合わせて調整できます これはスローモーションエフェクトの 作成にも使用されます 左側はサッカー選手が ゴールを喜んでいるビデオです 右側はスローモーションエフェクトを 適用した同じビデオです アクションを遅くすることで どれくらい喜んでいるかが よくわかる映像にすることができ プレーヤーの気持ちを 強調することができます 超高解像度スケーラは ビデオの解像度を向上させ 古いビデオの細部を復元できるため 写真補正やメディア復元などの アプリに最適です この例では 超高解像度エフェクトを適用することで ビデオの鮮明さと明瞭さが 向上されています 右側のボートの方が より詳細で明瞭に表現されています 超高解像度では 2つのMLモデルが利用可能で 1つは画像用で もう1つはビデオ用です 被写体ぶれは 映画制作で人気のある機能の1つで 観客が期待する自然な動きを 生み出すために不可欠です このエフェクトは様々なエフェクトを 作るのにも使用されます この例では 右側のビデオに 被写体ぶれエフェクトが適用されています エフェクトによりバイカーが 疾走しているように 見せることができます また このエフェクトは 左側のビデオのような ガタガタした動きを滑らかにし より見やすいビデオにすることができます もう1つの非常に役立つエフェクトは テンポラルノイズフィルタです これは前後の参照フレームを使用して 推測されたモーションに基づいています ビデオの一時的なノイズや アーティファクトを除去するのに役立ちます ビデオを圧縮しやすくなり ビデオの画質も向上させることができます 左側の木のビデオには たくさんのカラーノイズがあります エフェクトを適用した右側のビデオでは だいぶきれいになっています 特に 交通標識のノイズが減っています 低遅延フレーム補間エフェクトでは フレームレートをリアルタイムで アップサンプリングすることができます オプションで 解像度を アップサンプリングすることもできます 左側の女性が歩きながらカメラに 話している低フレームレートのビデオでは 映像が途切れ途切れになっています 右側の改善したビデオでは よりスムーズになって見やすくなっています 低遅延ビデオ超高解像度エフェクトは 軽量の超高解像度スケーラです このエフェクトは特にネットワーク状況が よくない場合でも ビデオ会議を快適に 行えるように最適化されています コーディングアーティファクトを減らし エッジを鮮明にすることで画質を改善します このエフェクトを実際に見てみましょう 左側の男性が話しているビデオは 解像度が低く画質もよくありません 右側の処理したビデオでは 解像度が高く圧縮アーティファクトも減り エッジが鮮明になって 顔の細かな特徴がわかるようになっています 次に これらのエフェクトをどのように アプリに統合できるかについて説明します アプリとフレームワークの間でどのように データがやり取りされるのか説明します クリップを処理する主な手順 についても説明します VTFrameProcessor APIを 利用するには アプリにVideo Toolboxフレームワークを インポートする必要があります その後 2つの主な手順で クリップを処理できます 最初の手順はエフェクトを選択することです この段階で アプリは処理セッションを開始し 一連の設定を提供して セッション全体にエフェクトを どのように使用するかを説明します セッションが作成されたら アプリは フレームを処理する VTFrameProcessorオブジェクトを 取得します VTFrameProcessorは フレームベースのAPIであるため 入力ビデオフレームをパラメータと一緒に 1つずつ送信する必要があります 処理が完了すると フレームワークから 出力フレームが返されます VTFrameProcessor APIを活用できる 多数のユースケースがあります その例をいくつか見ていき それらの実装方法を紹介します その前に 話しておきたい点として このプレゼンテーションには 参考資料として完全に機能する サンプルコードが添付されています デモアプリにはこれらのエフェクトを試せる テストクリップが用意されています ここではビデオ編集とライブビデオの改善の 2つのユースケースを見ていきましょう フレームレート変換や超高解像度 また 被写体ぶれやテンポラルノイズフィルタは いずれもビデオの画質が 最も重要視される ビデオ編集アプリに とても適しています フレームレート変換から見ていきましょう フレームレート変換では ビデオクリップのフレーム数を 増やす処理が行われます この処理は 新しいフレームを合成し それらを既存のフレームの間に 挿入することによって行われます 通常は再生の滑らかさを 向上させるために行われます 特にソースとターゲットで ディスプレイのフレームレートが異なるため 画像がカクつく場合に行われます このエフェクトはフレームの欠落による ギャップを埋めるのに役立ちます また スローモーションエフェクトを 作る場合にも使用されます これは映画制作でよく使われるエフェクトで アクションシーンをゆっくり再生することで 視覚的な印象を強める 効果があります スポーツでは ゲームの決定的な瞬間を 強調したり分析したりするために スローモーションが使用されます 左側にはダンスの基本ステップを 練習する男性のビデオが示されています 右側はスローモーションエフェクトを 適用した同じビデオです エフェクトを適用することで 視聴者がダンスの複雑な動きを ゆっくり見ることが できるようになるだけでなく より魅力的な映像にすることができます ではVTFrameProcessor APIを 使用して 実際にフレームレート変換を 実装してみましょう 最初に エフェクト用のセッションを 作成します これを行うには VTFrameProcessor オブジェクトを作成します 次に 設定オブジェクトを作成します VTFrameRateConversion Configuration型を フレームレート変換には使用します 設定を初期化するには 入力フレームの幅や高さ オプティカルフローを 事前に計算するかどうか 画質レベルや アルゴリズムのリビジョンなど いくつかの設定を指定する必要があります これでセッション開始メソッドを呼び出し フレーム処理エンジンを 初期化することができます 次に パラメータオブジェクトを使用して フレームを処理しますが それには VTFrameRateConversion Parameters型の オブジェクトを使用する必要があります パラメータクラスを使用する前に 必要な バッファをすべて割り当てる必要があります 一般的に 入出力フレームのバッファは すべて呼び出し元によって割り当てられます 設定クラスのソースと宛先の ピクセルバッファ属性を使用して CVPixelBufferプールを設定できます 最初に現在のソースフレームオブジェクトと 次のフレームオブジェクトを作成します 次に interpolationPhase配列を作成し 補間されたフレームを挿入する 場所を指定します 配列サイズは フレームを何個補間するかを示しています 最後に バッファを使用して 出力を受信する宛先配列を作成します これはinterpolationPhase配列と 同じサイズになります バッファの準備ができたので 残りのパラメータを設定します ここではオプティカルフローをnilに設定し プロセッサがフローを 計算できるようにしました また フレームを順番に送信するか ランダムに送信するかを示す 送信モードも設定しました VTFrameRateConversion Parametersが作成されたら process関数を呼び出して 実際の処理を行うことができます 要約すると各エフェクトは 2種類のクラスによって定義されます 1つは エフェクトの処理セッションの 設定方法を定義するVTFrame ProcessorConfigurationクラスと もう1つは 入力フレームと出力フレーム また関連するすべての パラメータを定義するVTFrame ProcessorParametersクラスです アプリを開発するときに行うべき 重要な決定事項は オプティカルフローを 事前に計算するかどうかです フロー計算は負荷が大きいため アプリによっては事前にフロー計算を行い レンダリング時のパフォーマンスを 向上させている場合があります オプティカルフローを事前に計算するには VTOpticalFlowConfigurationクラスと VTOpticalFlowParametersクラスを 使います 事前に計算されたフローパラメータの 使用を無効に設定した場合 フレームワークは フローをその場で計算します
次に もう1つの重要な ビデオ編集機能について説明します それは被写体ぶれです 被写体ぶれは 遅いシャッター速度をシミュレートし 移動するオブジェクトに ぼかしたエフェクトを作成します ぼかしの強さは APIを介して調整でき どれくらいぼかすかをコントロールできます このエフェクトは 動きを自然に見せたり 高速で移動する物体にスピード感を加えて 芸術性を高めたりするためなど 様々な状況で使用されます 左側は高速道路の タイムラプスビデオです 被写体ぶれエフェクトを適用した 右側の映像はより流動的になっています タイムラプスビデオに被写体ぶれを 適用すると 自然な動きが再現され よりリアルに見せることができ 静止画が連続している感じを軽減できます 被写体ぶれ処理セッションを作成するには VTMotionBlurConfigurationを使います 参考として 設定方法がよく似ている フレームレート変換の例を参照できます 次に VTMotionBlurParameters オブジェクトを初期化してフレームを処理する 方法を紹介します 被写体ぶれには その次とその前の 2つの参照フレームが必要になります クリップの最初のフレームで 前のフレームをnilに設定し クリップの最後で 次のフレームを nilに設定する必要があります フレームバッファの準備ができたので VTMotionBlurParametersを作成します フローパラメータをnilに設定して プロセッサにオプティカルフローを計算させます 次に ぼかしの強さを 1〜100の範囲で選択します 被写体ぶれパラメータを作成したら process関数を呼び出して 実際の処理を開始できます 次に ビデオ会議や ライブストリーミングなど リアルタイムで使用できるように設計された いくつかの機能について説明します テンポラルノイズフィルタや 低遅延フレーム補間 超高解像エフェクトはいずれもリアルタイムで 使用できるように設計されています これらでは パフォーマンスを意識しながら 画質を向上させることができます 低遅延エフェクトの場合 通常 画質の向上は 受信側のデバイス上で行われます 次に これらのエフェクトの いくつかを見てみましょう 最初に 低遅延超高解像度エフェクトから 見てみましょう このエフェクトを実装するにはLowLatency SuperResolutionScalerConfigurationと Parametersクラスを使用します どちらのクラスも使い方は簡単です 設定クラスに必要なのは フレームの幅と高さと スケーリング比のみで パラメータクラスに必要なのは ソースと宛先のフレームバッファのみです この例は 低遅延超高解像度により ビデオ会議セッションの画質が どのように向上するかを示しています 左側のビデオでは ビデオ通話をしている ひげを生やした男性が 話したり笑ったり身を振ったりしています 解像度が低いため ぼやけて見えます 超高解像度を 適用すると 右側のビデオのように 男性の顔 特にひげの質感が 大幅に鮮明になっています 低遅延フレーム補間も リアルタイムのビデオ会議の画質を 向上させることが できるように設計されています これはビデオ通話アプリに 非常に有効なエフェクトで 特に接続速度が遅い場合に効果的です このエフェクトを適用するには 適切なバージョンの LowLatencyFrame InterpolationConfigurationと Parametersクラスを使用します 低遅延フレーム補間により どのようにカクつきが滑らかになり ストリーミング体験が快適なものになるか については先ほど示しました このAPIには フレームレート倍増機能と 解像度アップスケーリング機能を 1つのフィルタにまとめた 追加のユーティリティが用意されています
処理後は女性の顔の特徴や 背景がより鮮明になり ストリーミングがよりスムーズです Video Toolboxフレームワークには ハードウェアビデオエンコーディング機能や デコーディング機能への直接アクセスなど 多くの機能が事前に用意されています これにより ビデオの圧縮や解凍 またピクセル形式の変換などの サービスが可能になります VTFrameProcessor APIが 追加されたことにより デベロッパはさらに魅力的な アプリを作成できるようになりました VTFrameProcessor APIについて 学ぶことができました 今すぐ これらのエフェクトを アプリに統合しましょう スローモーションや被写体ぶれなどの新しい エフェクトでビデオ編集機能を強化しましょう 低遅延超高解像度や フレーム補間エフェクトを使って ライブストリーミング体験を 向上させましょう これらは VTFrameProcessor APIで できるようになることの ほんの一例にすぎません ビデオのご視聴ありがとうございました 皆さんの動画を見るのを 楽しみにしています
-
-
8:06 - Frame rate conversion configuration
// Frame rate conversion configuration let processor = VTFrameProcessor() guard let configuration = VTFrameRateConversionConfiguration(frameWidth: width, frameHeight: height, usePrecomputedFlow: false, qualityPrioritization: .normal, revision: .revision1) else { throw Fault.failedToCreateFRCConfiguration } try processor.startSession(configuration: configuration)
-
8:56 - Frame rate conversion buffer allocation
// Frame rate conversion buffer allocation //use sourcePixelBufferAttributes and destinationPixelBufferAttributes property of VTFrameRateConversionConfiguration to create source and destination CVPixelBuffer pools sourceFrame = VTFrameProcessorFrame(buffer: curPixelBuffer, presentationTimeStamp: sourcePTS) nextFrame = VTFrameProcessorFrame(buffer: nextPixelBuffer, presentationTimeStamp: nextPTS) // Interpolate 3 frames between reference frames for 4x slow-mo var interpolationPhase: [Float] = [0.25, 0.5, 0.75] //create destinationFrames let destinationFrames = try framesBetween(firstPTS: sourcePTS, lastPTS: nextPTS, interpolationIntervals: intervals)
-
9:48 - Frame rate conversion parameters
// Frame rate conversion parameters guard let parameters = VTFrameRateConversionParameters(sourceFrame: sourceFrame, nextFrame: nextFrame, opticalFlow: nil, interpolationPhase: interpolationPhase, submissionMode: .sequential, destinationFrames: destinationFrames) else { throw Fault.failedToCreateFRCParameters } try await processor.process(parameters: parameters)
-
12:35 - Motion blur process parameters
// Motion blur process parameters sourceFrame = VTFrameProcessorFrame(buffer: curPixelBuffer, presentationTimeStamp: sourcePTS) nextFrame = VTFrameProcessorFrame(buffer: nextPixelBuffer, presentationTimeStamp: nextPTS) previousFrame = VTFrameProcessorFrame(buffer: prevPixelBuffer, presentationTimeStamp: prevPTS) destinationFrame = VTFrameProcessorFrame(buffer: destPixelBuffer, presentationTimeStamp: sourcePTS) guard let parameters = VTMotionBlurParameters(sourceFrame: currentFrame, nextFrame: nextFrame, previousFrame: previousFrame, nextOpticalFlow: nil, previousOpticalFlow: nil, motionBlurStrength: strength, submissionMode: .sequential, destinationFrame: destinationFrame) else { throw Fault.failedToCreateMotionBlurParameters } try await processor.process(parameters: parameters)
-