サンプル / 2 値ブローブ解析

ここでは主に下記についての説明を行っています。

  • 構造体配列の取り扱い

  • 関数呼び出しにおけるダブルポインタ型引数の指定


以下では 2 値ブローブ解析を行う例を示していますが、 得られた解析結果からブローブ番号配列を取得する際に、 "構造体配列" と "ダブルポインタ型引数" が使用されています。

C 言語
FHANDLE measure = NULL;

{
    F_MEASURE_PARAMS params;
    PNT_T offset;
    INT err;

    // ブローブ解析パラメータの設定
    params.max_runs = 0;
    params.max_blobs = 0;
    params.max_rows = 0;
    params.color_mode = F_MEASURE_BLACKFG;
    params.neighborhood = 8;
    params.precalc_features = 0;
    params.keep_results_after_overflow = FALSE;

    offset.x = 0;
    offset.y = 0;


    // 2 値ブローブ解析の実行
    measure = fnFIE_measure_execute(
        src, offset, &params, &err
    );
}

{
    const UINT filter_num = 3;
    F_MEASURE_FILTER_RANGE filters[filter_num];

    UINT * blob_numbers = NULL;
    UINT blob_num = 0;
    UINT i;

    // フィルタ配列の設定
    filters[0].type = F_FEATURE_XDIFF;
    filters[0].min = 20;
    filters[0].max = 100;
    filters[1].type = F_FEATURE_YDIFF;
    filters[1].min = 20;
    filters[1].max = 100;
    filters[2].type = F_FEATURE_AREA;
    filters[2].min = 50;
    filters[2].max = 10000;

    // ブローブ番号配列の取得
    fnFIE_measure_get_list(
        measure, filters, filter_num, &blob_numbers, &blob_num
    );


    for( i = 0; i < blob_num; i ++ ){
        DPNT_T points[4];

        // 外接長方形の頂点座標取得
        fnFIE_measure_get_rect2pos(
            measure, blob_numbers[i], points
        );

        // points へ取得した頂点座標の使用 (省略 ...)
    }


    fnOAL_free( blob_numbers );
}


fnFIE_free_object( measure );
Python
err = pyfie.INT()


# ブローブ解析パラメータの設定
params = pyfie.F_MEASURE_PARAMS(
    max_runs = 0,
    max_blobs = 0,
    max_rows = 0,
    color_mode = pyfie.f_measure_color_mode.F_MEASURE_BLACKFG,
    neighborhood = 8,
    precalc_features = 0,
    keep_results_after_overflow = False
)


# 2 値ブローブ解析の実行
measure = pyfie.fnFIE_measure_execute(
    src, (0, 0), params, err
)


# フィルタ配列の設定
filter_num = 3
filters = pyfie.F_MEASURE_FILTER_RANGE.ARRAY(filter_num)

filters.value = (
    (pyfie.F_FEATURE_XDIFF, 20, 100),
    (pyfie.F_FEATURE_YDIFF, 20, 100),
    (pyfie.F_FEATURE_AREA, 50, 10000)
)


# ブローブ番号配列の取得
blob_numbers = pyfie.UINT.PTR()
blob_num = pyfie.UINT()

pyfie.fnFIE_measure_get_list(
    measure, filters, filter_num, blob_numbers.ref, blob_num.ref
)


for i in range(blob_num):
    # PyFIE 関数から結果を受け取るために PyFIE 配列を使用.
    points = pyfie.DPNT_T.ARRAY(4)

    # 外接長方形の頂点座標取得
    pyfie.fnFIE_measure_get_rect2pos(
        measure, blob_numbers[i], points
    )

    # points へ取得した頂点座標の使用 (省略 ...)


# fnFIE_measure_get_list() により確保された
# ブローブ番号配列は解放しなければならない.
blob_numbers.fnOAL_free()
  • 変数 src は確保済の 2 値画像オブジェクト(FHANDLE) であるものとします


まず "フィルタ配列の設定" では、 構造体 F_MEASURE_FILTER_RANGE の配列を作成し(filters)、 各要素に対して値の設定を行っています。 その際、 配列の属性 value によりタプルを使った全要素に対する一括代入を行っています。 また、 配列の各要素に設定する値としてもタプルを使用していますが、 これは "PyFIE 構造体のオブジェクト変換" により可能となります。 ここで行っている構造体配列 filters の要素設定は下記 2 つの例と等価となります。

Python
filters[0].type = pyfie.F_FEATURE_XDIFF
filters[0].min = 20
filters[0].max = 100
filters[1].type = pyfie.F_FEATURE_YDIFF
filters[1].min = 20
filters[1].max = 100
filters[2].type = pyfie.F_FEATURE_AREA
filters[2].min = 50
filters[2].max = 10000
Python
filters[0] = (pyfie.F_FEATURE_XDIFF, 20, 100)
filters[1] = (pyfie.F_FEATURE_YDIFF, 20, 100)
filters[2] = (pyfie.F_FEATURE_AREA, 50, 10000)

つぎに "ブローブ番号配列の取得" では、 fnFIE_measure_get_list() の内部で確保される "ブローブ番号配列" を UINT 型のポインタ blob_numbers に受け取っています。 その際、 UINT 型のポインタ(C 言語における UINT *)は PyFIE では UINT.PTR となりますので、 そのインスタンスを blob_numbers として作成し、 fnFIE_measure_get_list() の引数には そのアドレスとなる(C 言語における & 演算子に相当する)属性 ref を指定します。 ( "PyFIE ポインタ型のオブジェクト変換" により関数引数にアドレスを指定する際の属性 ref は省略可能ですが ここでは明示的に指定を行っています)

このようにして PyFIE 関数内部で確保されたメモリ領域は、 使用した後に解放する必要がありますので、 fnFIE_measure_get_list() のドキュメント(FIE リファレンスマニュアル参照)に従い fnOAL_free() を使って解放します。