next up previous
Next: 各クラスのAPI詳細 Up: 各クラスの概要 Previous: MalibBuffer

Subsections

MalibFilter

各種の画像処理を実装するフィルタに関する抽象クラスである。 このクラスのサブクラスはバッファからのデータを入力とし、 バーチャル関数malib_source_write_frame_data()の実装により 各種のフィルタ処理を行なう。

MalibFilterの重要なサブクラスのひとつにMalibMergerがある。 MalibFilterがひとつのバッファからの入力を前提としているのに対し、 MalibMergerでは複数のバッファからの入力に基づく処理を前提としてい るとの違いがある。

メンバ

MalibFilterのメンバ変数には、上位クラスのMalibSourceに加えて、 入力となる前段のバッファへのポインタ、および接続可能なデータ種別を表す フラグacceptableが用意される。

またMalibFilterクラスは抽象クラスであるため、それ自体のオブジェクトは生成され ないが、malib_filter_set_buffer()、 malib_filter_set_frame_info()などの リファレンスカウンタ操作を備えたバッファやサンプルフレーム情報オブジェクト を接続するための関数のように、いくつか重要な関数が用意されている。

入力可能なデータ形式の指定

malib_source_write_frame_data()を実装する各フィルタの 画像処理関数は、その入力データ形式に制限が加わる場合が多い。 例えば、RGBデータをグレースケールに変換するフィルタ MalibRgb2Greyでは、入力データ形式はRGBカラーモデルに限定される (図3.11)。
  
Figure 3.11: フィルタに入力できるデータ形式の選別
\includegraphics{images/filteracceptable.eps}

これらの制限は、メンバ変数acceptableに記述する。その値としては、 frame.hで定義されるカラーモデル値を用いることができる。カラーモデルの 値は次に示すとおりビットフィールドに関して独立の値となっており、 論理和を取ることで複数の入力許容性を示すことができる。

#define MALIB_FRAME_COLORMODEL_RGB      0x0001
#define MALIB_FRAME_COLORMODEL_GREY     0x0002
#define MALIB_FRAME_COLORMODEL_BW       0x0004
#define MALIB_FRAME_COLORMODEL_RGB_A    0x0008
#define MALIB_FRAME_COLORMODEL_GREY_A   0x0010
#define MALIB_FRAME_COLORMODEL_BW_A     0x0020

フィルタクラスの各サブクラスを実装するにあたっては、 そのコンストラクタの記述を簡潔にするためのマクロ定義 MALIB_FILTER_GENERIC_NEW(klass, vtbl, accepts) などが用意されており、この時点でacceptableの値を設定することが できる。

例えばMalibMovingaveは、その入力形式として RGBカラーモデルまたはグレースケールモデルのデータを許容する。 このクラスのコンストラクタでは、下記のように論理和をとり その旨を指定することが可能となっている。

MalibMovingave*
malib_movingave_new ()
{
  MALIB_FILTER_GENERIC_NEW ( MalibMovingave, &malib_movingave_class,
                             (MALIB_FRAME_COLORMODEL_RGB
                              | MALIB_FRAME_COLORMODEL_GREY) );
}

MalibFilterのサブクラスの実装例

フィルタを実現するにあたって、最低限記述する必要がある要素は以下のものである。
へッダファイル
    
Cソースファイル
    

以下、例としてRGBカラーデータをグレースケールに変換するフィルタの実装に 基づいて説明する(rgb2grey.c)。

バーチャル関数テーブルの定義

フィルタはバーチャル関数テーブルとして、MlaibObjectからデストラクタを、 MalibSourceから画像処理関数を、それぞれ継承する。このクラスでは とくにフィルタ自体のデータ構造に特殊な追加を加えていないので、 デストラクタとしては フィルタに関するデフォルトのデストラクタmalib_fitler_delete を指定すればよい。write_frame_dataの値は、このクラスで独自に 定義する非公開メンバ関数を指定する。
static MalibRgb2GreyClass malib_rgb2grey_class = 
{
  (void (*)(MalibObject*))               malib_filter_delete,
  (void (*)(MalibSource*, MalibFrame*))  malib_rgb2grey_write_frame_data
};

コンストラクタ

コンストラクタで入力を許容するデータの形式を指定する。 コンストラクタの記述には、記述を簡潔にするためのマクロ定義が filter.hで用意されているので、一般的なデータ構造を持つ フィルタであればそれを利用することができる。マクロ定義の 詳細については次章のAPI解説を参照のこと。
MalibRgb2Grey*
malib_rgb2grey_new ()
{
  MALIB_FILTER_GENERIC_NEW ( MalibRgb2Grey, &malib_rgb2grey_class,
                             MALIB_FRAME_COLORMODEL_RGB );
}

MalibRgb2Grey*
malib_rgb2grey_new_with_buf (MalibBuffer* buf)
{
  MALIB_FILTER_GENERIC_NEW_WITH_BUF ( MalibRgb2Grey, malib_rgb2grey_new,
                                      malib_rgb2grey_set_buffer, buf );
}

なおこの例では、グレースケールに変換するためサンプルフレーム情報を 入れ替える必要があり、そのためバッファをセットする関数として独自の 関数である malib_rgb2grey_set_buffer を指定している。 この関数では、次のようにカラーモデルを指定する形式のバッファ設定 関数を呼ぶ。

void
malib_rgb2grey_set_buffer (MalibRgb2Grey* filter, MalibBuffer* buf)
{
  /* create new frame, which has almost all the same information
     except data format (rgb -> grey), and timestamp */
  malib_filter_set_buffer_with_colormodel ((MalibFilter*)filter, buf,
                                           MALIB_FRAME_COLORMODEL_GREY);
}

画像フィルタ処理関数

最後に画像フィルタ処理の中心部を担う画像フィルタ処理関数を記述する。
static void
malib_rgb2grey_write_frame_data (MalibRgb2Grey* filter, MalibFrame* frame)
{
  MalibBuffer* input;
  unsigned int i, j;
  unsigned int image_size;

  /* the flag whether we need to propagate previous section */
  int need_increment = 0;
  
  /* pointers to rgb frame data and data area to store 
     the result of calculation */
  int* rgb;
  int* grey;

  g_return_if_fail (filter && frame);
  g_return_if_fail (((MalibFilter*)filter)->buf && frame->data);

  input = ((MalibFilter*)filter)->buf;
  grey  = frame->data;
  
  /* increment previous buffer data */
  MALIB_OBJECT_COUNT_REFERENCES (filter, need_increment);
  if (need_increment)
    {
      malib_holder_increment_frame ((MalibHolder*)input);
    }

  /* get pointers to rgb frame data */
  rgb = malib_buffer_get_current_frame (input) ->data;

  image_size = malib_filter_calc_output_image_size 
                                        ((MalibFilter*) filter);

  /* calculate greyscale value of rgb data */
  for (i = 0, j = 0; i < image_size; i++, j += 3)
    {
      grey[i] = (int) (0.299f * (float) rgb[j] 
                       + 0.587f * (float) rgb[j+1]
                       + 0.114f * (float) rgb[j+2]);
    }
}

重要な点は、実際の画像生成処理を実施する前にリファレンスカウンタの チェックを行ない、必要であれば前段のバッファのフレームを更新することを 忘れないことである。上記のリスト中では、次の部分が該当する。

/* increment previous buffer data */
MALIB_OBJECT_COUNT_REFERENCES (filter, need_increment);
if (need_increment)
  {
    malib_holder_increment_frame ((MalibHolder*)input);
  }

   
多入力フィルタ(MalibMerger)

MalibMergerは複数のバッファを入力にとる特殊なフィルタのベースクラスと なる抽象クラスとして用意されている。複数のバッファを入力にとるクラスとしては、 画像データの重ねあわせを行なうMalibOverlap、画像に部分的なマスク処理を 行なうMalibMaskingなどがある。

メンバ

ひとつのバッファを入力にとるMalibFilterに加え、MalibMergerでは ふたつめ以降の入力バッファへのポインタを保持する必要がある。 また各入力で許容できるデータ形式が異なる場合がある。例えば マスク処理を行なうMalibMaskingにおいては、マスクされる側の 入力はRGBカラーまたはグレースケールを対象とするがマスク情報を 入力する側は白黒二値でマスクを表現するためBWモデルのデータ形式を要求する。

そこで構造体 MalibMergerBufInfo (バッファ情報構造体)を導入する。

typedef struct _MalibMergerBufInfo MalibMergerBufInfo;

/* optional buffer information */
struct _MalibMergerBufInfo
{
  /* see filter.h */
  MalibBuffer*		buf;
  unsigned int		acceptable;
};

この構造体は入力バッファへのポインタと許容するデータ形式のフラグを組にした もので、MalibMergerはこの構造体の配列へのポインタを 持つ。こうすることにより3個以上の入力を同じ枠組みで取扱うことが可能になる。 また配列の最後にはNULL値を書込んでおくことで、配列の終了を判定する ものとしておく(図3.12)。


  
Figure 3.12: 複数バッファの入力を可能にするMalibMergerのデータ構造
\includegraphics{images/mergerblockfig.eps}

なおそれぞれのバッファの取扱い(接続、消去など)は、MalibFilterでの リンクの扱いに準じる。

フレームの更新処理

フィルタ処理の記述に関しては、通常のフィルタと同様にリファレンスカウンタ のチェックとそれに伴う前段バッファのフレーム更新処理を忘れずに記述する。

前段バッファのフレーム更新処理は、全ての入力バッファについてフレーム更新の ための関数呼び出しを行なう。 例えば、MalibOverlapでの該当部分を抜粋すると以下のようになる。

/* increment previous buffer data */
MALIB_OBJECT_COUNT_REFERENCES (filter, need_increment);
if (need_increment)
  {
    malib_holder_increment_frame ((MalibHolder*)input[0]);
    malib_holder_increment_frame ((MalibHolder*)input[1]);
  }



Jun IIO
2001-06-14