フィルタモジュールの作成

ここではライブ画像に2値化処理を実行するフレームフィルタの作成方法について説明します。
以下の処理の手順について紹介します。

  • フィルタモジュール作成のためのVisual Studio プロジェクトをセットアップする
  • フィルタモジュールからロードできるフレームフィルタクラスを作成する
  • フレームフィルタにダイアログを追加する

Visual Studio プロジェクトとフレームフィルタモジュールは IC Imaging Controlインストールディレクトリのsamples\VCx\DemoFiltersにあります。VC++2010 バージョンでは%TOPLEVEL%\Samples\VC10となります。

ここではフレームフィルタを記述する: 2値化プログラマーズガイド>フレームフィルタの記述: 二値化処理フレームフィルタの記述: 二値化内で作成されたフィルタを使用します。フレームフィルタの実装についてはこのページをご覧ください。

フレームフィルタモジュール用のVisual Studioプロジェクトをセットアップする

Visual C++をお使いであればフレームフィルタモジュールウィザードプログラマーズガイド>フレームフィルタモジュールウィザードを使って簡単にプロジェクトが作成できます。

そのようなプロジェクトをどのようにして作成できるか詳しく知りたい場合、 もしくはVisual C++の別のバージョンを使用している場合には下記のことを実行してください。

プロジェクトテンプレートVisual C++ Projects -> Win32 -> Win32 Projectを使用して新しいプロジェクトを作成する。アプリケーションタイプとしてDLLを選択する。
VC++プロジェクト作成の手順プログラマーズガイド>はじめに:Visual Studio C++>プロジェクト作成の手順>プロジェクトプロパティ で説明されている通りにコンパイラーセッティングを設定する。

プロジェクトのアウトプットファイル名を<name>.ftfとする。フィルタローダーはこのファイル拡張子のモジュールのみをロードします。

stdafx.hを開き以下のコードを記述します。

#include <tisudshl.h>
#include <FilterFactory.h>

通常の tisudshl.hに加えて、FilterFactory.hもインクルードする必要があります。

フレームフィルタクラスの実装

ではフレームフィルタを記述する: 2値化プログラマーズガイド>フレームフィルタの記述: 二値化処理フレームフィルタの記述: 二値化で作成した二値化フィルタをフィルタモジュール内で動作するように拡張したいと思います。

フィルタをロードするジェネリックアプリケーションはフィルタのインターフェース ( CBinarizationFilter::enableCBinarizationFilter::setThreshold メソッド)を知っています。そのプログラムからフィルタパラメータを設定するためにIFrameFilterクラスライブラリリファレンス>クラス>IFrameFilterFrameFilterImplクラスライブラリリファレンス>クラス>FrameFilterImplにはジェネリックフィルタインターフェースが実装されております。アプリケーションはIFrameFilter::getAvailableParametersクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::getAvailableParameters Method を使ってフィルタが対応しているパラメータを見つけ出し、IFrameFilter::setParameterクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::setParameter Methodをコールすることでパラメータの値を変更します。

二値化フィルタをそれらのパラメータに対応させるには、FrameFilterImpl::addBoolParamクラスライブラリリファレンス>クラス>FrameFilterImpl>FrameFilterImpl::addBoolParam Method か他のパラメータ登録メソッドを使用する必要があります。2つのパラメータを登録するためCBinarizationFilterのコンストラクタを拡張します。

CBinarizationFilter::CBinarizationFilter()
  :    m_bEnabled( false ),
    m_threshold( 127 )
{
  // 二値化の有効/無効化を設定するための 'enable' パラメータの追加
  addBoolParam( "enable", &CBinarizationFilter::getEnable, &CBinarizationFilter::setEnable );       

  // 二値化の際のしきい値設定のための'threshold' パラメータの追加     
  addLongParam( "threshold", &CBinarizationFilter::getThreshold, &CBinarizationFilter::setThreshold );
}

登録関数の最初のパラメータは、アプリケーションがそのパラメータにアクセスするための名前となります。
2番目と3番目のパラメータはCBinarizationFilterのメンバ関数の名前となります。以下のコードによって古いenablesetThreshold メソッドを新しいものに入れ替えます。

public:
  // 二値化の有効/無効化
  DShowLib::tFilterError getEnable( bool& bEnable );
  DShowLib::tFilterError setEnable( bool bEnable );

   // 二値化の際のしきい値を設定
  DShowLib::tFilterError getThreshold( long& threshold );
  DShowLib::tFilterError setThreshold( long threshold );

private:
  bool m_bEnabled;
  int m_threshold;
};

これらのメソッドはフィルタをロードしたプログラムがsetParameter( "enable", true )、もしくはsetParameter( "threshold", 100 )をコールした時に呼び出されます。

実装はとても簡単です。

/*  
*    二値化の状態を'enabled' として返す
*/
tFilterError CBinarizationFilter::getEnable( bool& bEnable )
{     
  bEnable = m_bEnabled;     
  return eNO_ERROR;     
}  

/*
*    二値化の状態を'enabled'に設定
*/
tFilterError CBinarizationFilter::setEnable( bool bEnable )
{     
  m_bEnabled = bEnable;     
  return eNO_ERROR;
}

/*
*    二値化のしきい値を返す
*/
tFilterError CBinarizationFilter::getThreshold( long& threshold )
{     
  threshold = m_threshold;     
  return eNO_ERROR;     
}

/*
*    二値化のしきい値を設定
*/
tFilterError CBinarizationFilter::setThreshold( long threshold )
{     
  m_threshold = threshold;     
  return eNO_ERROR;
}

ジェネリックアプリケーションで動作するフィルタを作成したので、メソッドgetStaticFilterInfoを変更し、フィルタをeFC_GENERICとして宣言できるようにします。

FilterInfo CBinarizationFilter::getStaticFilterInfo()
{
  // フィルタ名を返し、eFC_GENERICとして宣言する
  FilterInfo fi = { L"Demo_Binarization", L"", eFC_GENERIC };
  return fi;
}

フレームフィルタの登録

フィルタモジュールのメインファイルに移動し、FILTERDLL_BEGIN_EXPORTFILTERDLL_END_EXPORTの間の部分にフィルタの名登録用のFILTERDLL_REGISTER_FILTERコードをいれていきます。

FILTERDLL_BEGIN_EXPORT()
  FILTERDLL_REGISTER_FILTER(CRotateTransform)
  FILTERDLL_REGISTER_FILTER(CDeNoiseTransform)
  FILTERDLL_REGISTER_FILTER(CSnapFilter)
  FILTERDLL_REGISTER_FILTER(CBinarizationFilter)
FILTERDLL_END_EXPORT()

フレームフィルタにダイアログを追加する

フィルタにユーザーインターフェースを追加するのにIFrameFilter::hasDialogクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::hasDialog MethodIFrameFilter::callDialogクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::callDialog Methodメソッドをオーバーライドすることができます。
hasDialogのデフォルトの実装ではfalseを返すため、これをtrueに変更します。

bool CBinarizationFilter::hasDialog() const
{
  return true;
}

callDialogの実装においてはIFrameFilter::getSettingsクラスライブラリリファレンス>クラス>IFrameFilter>IFrameFilter::getSettings Methodを使用して現在のフィルタ設定を保存します。そしてダイアログボックスを表示させることでフィルタのパラメータを変更できるようにします。もしユーザーがキャンセルボタンによってダイアログを閉じた場合、フィルタの設定が保存した値に戻ることになります。

bool    CBinarizationFilter::callDialog( HWND hParent )
{     
  // セッティングの保存     
  std::string data = getSettings();       
    
  // モーダルダイアログの表示     
  // このインスタンスへのポインタをWM_INITDIALOGに渡す     
  INT_PTR result = DialogBoxParam( g_hInst,     
                    MAKEINTRESOURCE(IDD_BINARIZATION_CONFIG),     
                    hParent,     
                    BinarizationConfigDlgProc,     
                    (LPARAM)this );

  // ユーザーが'cancel'をクリックした場合、セッティングを戻す。
  if( result == IDCANCEL )     
  {     
     setSettings( data );     
  }
    
  // ダイアログが表示された時にtrueを返す     
  return result >= 1;
}