フレームフィルタ

フレームフィルタを使うことによって、多様かつ効果的な画像データの編集が可能となります。他の機能に加えて、フレームフィルタは動画フォーマットの変更や変換、画像処理の実装、またどのフレームを処理するかの指定することもできます。

概要

IC Imaging Controlのフレームフィルタは、他のDirectShowライブラリと違ってDirectShowフィルタを使用するわけではありません。しかしそれらは画像ストリームを処理するDirectShowスレッドのコンテキスト内で実行されます。これによってプログラマーはDirectShowフィルタモジュールを作成して登録したり、パラメータ用にインターフェースを定義するする手間から解放されます。フレームフィルタはFrameFilterImplクラスライブラリリファレンス>クラス>FrameFilterImplFrameUpdateFilterImplクラスライブラリリファレンス>クラス>FrameUpdateFilterImplクラスから派生することで実装され、IFrameFilterクラスライブラリリファレンス>クラス>IFrameFilterクラスがそのパラメータへのアクセスを容易にします。フレームフィルタはフィルタモジュールの一部として実装することができますが、クラスがわかっていればアプリケーションで直接作成することも可能です。フレームフィルタクラスやフレームフィルタモジュールの作成を簡単に行えるようにVisual Studio .NET用のプロジェクトウィザードC++用のウィザードを使用したセットアップについてが用意されています。これらを使って少しのマウス操作でフィルタを作成することができます。フレームフィルタは基本的に画像処理という点においてDirectShowフィルタと同様のパフォーマンスを提供しながらも、はるかに容易に実装することができます。

フィルタカテゴリー

フレームフィルタの機能によって、新しいIC Imaging Controlベースで多種多様なアプリケーションの作成が可能となりました。この新しい機能をつかってどういったことができるかを紹介するために、フレームフィルタと共に実装可能なタスクのカテゴリーについて説明します。それらのうちいくつかはIC Imaging Controlに標準で備わっています。

Gate: ゲートフィルタ ゲートフィルタは不要なファイルを除去します。それは画像分析の結果やフレームカウント、タイムスタンプの情報に基づき決定されます。
Color Space Conversion: 色空間変換 あるカラーフォーマットから他のフォーマットへの変換は全てこのカテゴリーに属します。また、ピクセル深度の低減 e.g.10または12ビットのモノクロのフォーマットから8ビット分だけを抽出するというようなことも色空間変換とみなされます。ピクセル深度の低減は10,12ビットのモノクロ画像を表示するのに使用されます。色空間変換の例としてはstdfilters.ftfにあるDeBayerフィルタIC Imaging Controlスタンダードフィルタ>DeBayerフィルタがあげられます。BayerフォーマットのRawカラーデータをRGBに変換するフィルタです。
ROI: Region Of Interest (関心領域) このカテゴリーのフィルタは画像ストリームにおけるROI(関心領域)だけを切りだすことができます。stdfilters.ftf内にある ROI フィルタIC Imaging Controlスタンダードフィルタ>ROI (関心領域)フィルタ はこの機能を実装します。
Rotation: 回転・反転 このカテゴリーは画像の回転や反転を含みます。stdfilters.ftf内にあるRotate FlipフィルタIC Imaging Controlスタンダードフィルタ>Rotate Flip(回転・反転) フィルタは90度、180度、270度の回転と、水平、垂直軸での反転を可能にします。DemoFilter.ftf内にあるデモ用フィルタを使ってどのアングルにでも回転させることが可能ですが、あくまでデモの実装であり動作はかなり遅くなってしまいます。
Scaling: スケーリング スケールのアップ、ダウンは監視アプリケーション用などに使われる際にディスプレイのサイズやデータストレージの容量に合わせて調整する時に使用されます。
Sink: シンクフィルタ シンクフィルタはデータの消費先です。 画像ストリームをTransformメソッドにおいて完全に処理をして、IC Imaging Control シンクにはフレームを送りません。専門的で高度なコーデックを使用したい場合には シンクフィルタを実装してそのコーデックのAPIを組み込むといいでしょう。 大抵の専門的なコーデックはDirectShowコーデックではなくDLLであるためこの方法が必要になります。これらのコーデックは画像データを圧縮すると同時にファイルに書き込む機能を持つため、シンクは使われなくなっています。
もちろんFrameHandlerSinkMembufferCollectionを使って画像データにアクセスし、コーデックのAPIに送ることも可能です。その場合、画像データはシンクによってMembufferCollectionにコピーされますが、フレームフィルタを使用してコーデックを連結すればこのようなことはありません。言い換えればこのシンクフィルタを使用することでフレームごとにコピーする処理を省くことができるため、特に容量の大きなフレームを扱っている場合には劇的にパフォーマンスを向上させることが可能です。
Extraction: 抽出フィルタ 抽出フィルタは画像ストリームより特定のフレームだけを取り出し処理を行います。 e.g. 画像ファイルとしてディスクに保存するなど。画像ストリーム自体に変化が加えられることはなく、そのままシンクに送られます。MediaStreamSinkクラスライブラリリファレンス>クラス>MediaStreamSinkが圧縮された映像ファイルを作るのに対してこのフィルタは特定の画像を非圧縮で保存します。
Image Processing: 画像処理 出力として1枚だけ画像を作り出す画像処理関数は全て、フレームフィルタを使うことで簡単に実装が可能です。複数の画像を生成するための関数は特別に開発する必要があります。一つの方法としてはできあがった画像に出力画像を順番に書き込んでいくというものです。その関数によって画像ではなくデータが生成される場合 (e.g. ブロブ解析によってつくられたデータ)、アプリケーションはフィルタパラメータを使うことでこのデータを出力することができます。
Buffer Format Conversion:
バッファフォーマット変換
ほとんどの画像処理ライブラリは特殊なイメージバッファフォーマットを持っています。フレームフィルタは画像ストリームのイメージバッファをそういった特殊なフォーマットに変換するのにも使用できます。そうすることで FrameHandlerSinkクラスライブラリリファレンス>クラス>FrameHandlerSinkのリングバッファの要素が特殊なフォーマットのデータを含むことになります。よってこれらのバッファのデータを対応する画像処理ライブラリに直接渡されるようにすることができ、コピーする処理が省かれるため、システムの処理能力を向上させることになります。

フィルタタイプ

次にフレームフィルタの2つの基本タイプについて説明します。どちらも同様のパラメータへのアクセスを提供し、フレームに反映されます。

Transform Filter:変換フィルタ このタイプのフレームフィルタはFrameFilterImplクラスライブラリリファレンス>クラス>FrameFilterImplクラスより派生し、ビデオフォーマットの変換機能を実装します。それには幅や高さの変更、そしてカラーフォーマットの変換(e.g.Y800 から RGB24など)も含みます。
Update Filter:アップデートフィルタ このタイプのフレームフィルタはFrameUpdateFilterImplクラスライブラリリファレンス>クラス>FrameUpdateFilterImplクラスより派生します。Transform Filterとの違いとして、Update Filterはカラーフォーマットや画像サイズの変更は行いません。画像ストリームの処理を高速化するために、アップデートフィルタはフレームワークに画像データのを読み込むだけを行うように命令します。これによってフレームワークの最適化がされることになります。おおまかにいって、Update Filterは画像データに全く変更が加えられない時、あるいはほんの少数のピクセルのみ変化する時にのみ使用するものです。なぜならフィルタがFrameUpdateFilterImpl::modifiesDataクラスライブラリリファレンス>クラス>FrameUpdateFilterImpl>FrameUpdateFilterImpl::modifiesData Methodメソッドにおいてtrue を返し、画像データに変更を加えることを示した場合、フレームワークはFrameUpdateFilterImpl::updateInPlaceクラスライブラリリファレンス>クラス>FrameUpdateFilterImpl>FrameUpdateFilterImpl::updateInPlace Methodメソッドをコールする前にイメージバッファをコピーしなければならないからです。

既存のフレームフィルタを使用する

先ほど説明したように、フレームフィルタはアプリケーション内に直接作成したり、フィルタモジュールよりロードすることが可能です。 IC Imaging Controlはstdfilters.ftfモジュールに数種類かのフィルタを備えています。現在利用可能な全フィルタモジュールにあるフレームフィルタの一覧を見たい場合はFilterLoader::getAvailableFrameFiltersクラスライブラリリファレンス>クラス>FilterLoader>FilterLoader::getAvailableFrameFilters Methodメソッドをコールしてください。FilterLoader::setLoadPathクラスライブラリリファレンス>クラス>FilterLoader>FilterLoader::setLoadPath Methodメソッドで追加のフィルタモジュール用パスを指定することも可能です。FilterLoader::createFilterクラスライブラリリファレンス>クラス>FilterLoader>FilterLoader::createFilter Methodへのコールで一覧リストから選択されたフィルタのインスタンスを作成します。フィルタフレームインスタンスを取得できましたので、これを画像ストリーム上にある以下の3カ所に挿入することができます。

同じフレームフィルタのインスタンスを画像ストリーム上の複数箇所で使用しないでください。内部不整合を引き起こす可能性があります。特にFrameFilterImpl::notifyStartクラスライブラリリファレンス>クラス>FrameFilterImpl>FrameFilterImpl::notifyStart MethodFrameFilterImpl::notifyStopクラスライブラリリファレンス>クラス>FrameFilterImpl>FrameFilterImpl::notifyStop Methodが使われている場合にはこの恐れがあります。もし同じフィルタを複数個所に挿入する必要がある場合、別のインスタンスを使うようにしてください。

フレームフィルタの内部データにはパラメータインターフェースからアクセスすることができます。

IFrameFilter::getParameterクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::setParameter MethodIFrameFilter::setParameterクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::setParameter Methodメソッドを使うことで bool, int, long float,std::stringといった基本的なデータ型のフィルタからの読み取り、またはそこへの書き込みが可能となります。 バイナリデータのブロックは IFrameFilter::getDataクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::getData MethodIFrameFilter::setDataクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::setParameter Methodといったメソッドを使うことでフレームフィルタと交換することができます。フィルタのtransformメソッドはDirectShow スレッドの中で実行されるため、フィルタデータへの外部アクセスと内部アクセスを同期させることがとても重要になります。よってまず先にIFrameFilter::beginParamTransferクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::beginParamTransfer Methodへのコールがあり、その後に上記で述べた4つのメソッドへのコール、続いてIFrameFilter::endParamTransferクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::endParamTransfer Methodへのコールという順番にならなければいけません。

pFrameFilter->beginParamTransfer();

// setParameter と getParameterへのコールは全てここに

pFrameFilter->endParamTransfer();

フレームフィルタをFilter Inspectorプログラマーズガイド>フィルタインスペクタのような包括的アプリケーションで使用する場合、パラメータが双方向的に変更されるようダイアログを実装されることが望まれます。フレームフィルタはIFrameFilter::hasDialogクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::hasDialog Methodメソッドにおいてtrue を返すことでパラメータダイアログの提供を示唆します。IFrameFilter::callDialogクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::callDialog Method メソッドがコールされるとダイアログが表示されるはずです。

全てのフレームフィルタはIFrameFilter::getSettingsクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::getSettings MethodIFrameFilter::setSettingsクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::setSettings Methodメソッドを実装し内部データをシリアライズ化ができるようにしなければいけません。そしてデータの表示形式は文字列に対応する必要があります。

フレームフィルタ/フレームフィルタモジュールの作成

Visual Studio .NET では、ウィザードを使うことによって簡単なマウス操作だけでフレームフィルタ/フィルタモジュールの作成が可能です。詳細はプロジェクトウィザードC++用のウィザードを使用したセットアップについてをご参照ください。ウィザードがどういったものかを理解したいというのであれば、フレームフィルタを記述する: 2値化プログラマーズガイド>フレームフィルタの記述: 二値化処理フィルタモジュールの作成プログラマーズガイド>フィルタモジュールの作成において詳しく説明しております。