2次元エッジ操作
[ビジョンツール]


データ構造

struct  F_EDGE_CLUST
 エッジ点クラスタ構造体 [詳細]

関数

INT FVALGAPI fnFIE_edge_connecting (const F_DEDGE *pedges, INT edge_num, DOUBLE weight, DOUBLE threshold1, DOUBLE threshold2, INT area_size, INT area_overlap, INT min_clust_elem, INT mode, F_EDGE_CLUST **ppedge_clust, INT *pclust_num)
 [非推奨]エッジ点の連結
INT FVALGAPI fnFIE_free_edge_clust (F_EDGE_CLUST *pedge_clust, INT clust_num)
 エッジ点クラスタ配列の解放
INT FVALGAPI fnFIE_edge_connecting2 (const F_DEDGE *pedges, INT edge_num, DOUBLE angle_range, INT distance_range, INT min_clust_elem, INT max_clust_elem, F_EDGE_CLUST **ppedge_clust, INT *pclust_num)
 エッジ点の連結
INT FVALGAPI fnFIE_refilter_edge_by_mask (const F_DEDGE *src_edges, INT src_edge_num, FHANDLE hmask, INT mask_mode, F_DEDGE **dst_edges, INT *dst_edge_num)
 マスクによる エッジ点群のフィルタリング
INT FVALGAPI fnFIE_refilter_edge_by_clust (const F_DEDGE *src_edges, INT src_edge_num, const F_EDGE_CLUST *edge_clust, INT edge_clust_num, const INT *clust_idx, INT clust_idx_num, F_DEDGE **dst_edges, INT *dst_edge_num)
 クラスタ情報による エッジ点群のフィルタリング

関数

INT FVALGAPI fnFIE_edge_connecting ( const F_DEDGE pedges,
INT  edge_num,
DOUBLE  weight,
DOUBLE  threshold1,
DOUBLE  threshold2,
INT  area_size,
INT  area_overlap,
INT  min_clust_elem,
INT  mode,
F_EDGE_CLUST **  ppedge_clust,
INT *  pclust_num 
)

[非推奨]エッジ点の連結

非推奨:
本関数による処理結果は直感的な連結状態とならない場合があり、改善版として fnFIE_edge_connecting2() が提供されています。
本関数は後方互換性のために残されていますが、新規の開発では fnFIE_edge_connecting2() の使用を推奨します。
入力されたエッジ点群を連結します。 連結は、エッジ点間のユークリッド距離とエッジ勾配方向のなす角によって決定されます。 下図のように、入力されたエッジ点群が連結された曲線が生成されます。 エッジ点の連結条件は、パラメータにより調節することができます。 勾配方向についての詳細は 総合ドキュメントのエッジ角度 をご参照ください。

fie_edge_connect.png

本関数を応用することで、以下のような処理を構築することができます。 なお以下に示す処理は、一例となります。

  • 不連続な小さいクラックを、一つの大きなクラックとして表すことができる
  • 構成するエッジ点の個数が少ない曲線をノイズとして除去できる
  • 形状検査を構築するための要素技術として利用できる
入力データ( pedges ):
入力されるエッジ点は、 fnFIE_edge_sobel_subpix()fnFIE_edge_corr_subpix() によって 座標以外に勾配方向が求められている必要があります。 そのため、想定する勾配方向の範囲は、 $-\pi$pedges->q$\pi$ (単位:ラジアン) となります。 ただし、勾配方向の範囲は内部でチェックしていません。 範囲外の勾配方向が入力されてもエラーとはなりません。
エッジ勾配方向の重み( weight ):
エッジ勾配方向の重みは、エッジ点間の距離を1とした場合の割合を示しています。 エッジ勾配方向の重みは、 0.0 <= weight <= 1.0 の範囲で指定してください。 0を指定した場合は、エッジ点間の距離のみで連結のための計算をします。
評価式( threshold1 , threshold2 ):
評価値( エッジ点i,j の距離(非類似度) ) $D_{ij}$ を次のように定義します。 $D_{ij}$ が 0 に近いほど類似していることを表しています。

\[ D_{ij} = \sqrt{ d_{ij}^{2} + \left( s_{ij} \times weight \right)^{2} } \]

ここで、$d_{ij}$ は点i、j のユークリッド距離、$s_{ij}$ は点i、j それぞれのエッジ勾配方向のなす角となります。 なお $s_{ij}$ は、勾配方向のなす角の単位を、入力点群時点のラジアンから度へ変換された後に計算に用いられます。 つまり、 0 <= $s_{ij}$ <= 180(単位:度)の範囲となります。 また、 weight はエッジ勾配方向の重みとなります。
ここで得られた評価値 $D_{ij}$ と 2つのしきい値 threshold1threshold2 を比較することで、 連結、後述する再連結処理が実行されます。

再連結処理( mode ):
本関数におけるエッジ点の連結は、評価しきい値を基準として実行されます。 まずは、評価しきい値1( threshold1 )を基準として、エッジ点を連結します。 再連結処理が有効ならば、評価しきい値1で生成された曲線を、評価しきい値2( threshold2 )によって再連結します。 なお、評価しきい値1で連結されたエッジ点間の関係性は保持しています。
局所領域( area_size , area_overlap ):
本手法では、局所領域内の点群毎に連結性を求めます。 局所領域毎に求められた曲線を、全体で連結処理をします。 局所領域は、正方形で設定( area_size )されます。 また局所領域には、重なり部分( area_overlap )が存在します。 全体の連結処理では、重なり部分のエッジ点が利用されます。
出力データ( ppedge_clust ):
出力データは、以下に示す条件に従います。 なお、必要のなくなった曲線の情報( ppedge_clust )の配列は、必ず fnFIE_free_edge_clust() で解放してください。
  • 出力データは下図に示すように、 F_EDGE_CLUST の配列となります。 一つの F_EDGE_CLUST が一つの曲線を表しています。
  • 曲線には、開曲線または閉曲線の二種類があります。 閉曲線は、最初に格納されたエッジ点と最後に格納されたエッジ点が同じエッジ点となります。 開曲線は、最初と最後に格納されたエッジ点が異なります。
  • F_EDGE_CLUST に保持されているデータは、エッジ点の座標ではなく、入力されたエッジ点群配列のインデックスとなります。
  • F_EDGE_CLUST 配列の保存順序は処理された順になります。 曲線間の位置関係などに依存しません。

fie_edge_clust.png
推奨パラメータ
パラメータ名 推奨値
weight 0.07
threshold1 2.0
threshold2 4.0
area_size 10
area_overlap 3
min_clust_elem 3
引数:
[in] pedges エッジ点の配列(座標、勾配方向(rad))
[in] edge_num エッジ点の個数( 2 <= edge_num
[in] weight エッジ勾配方向の重み weight エッジ勾配方向のなす角の重み)( 0 <= weight <= 1 )
[in] threshold1 評価しきい値1:連結用( 0 < threshold1
[in] threshold2 評価しきい値2:再連結用( threshold1 < threshold2
[in] area_size 正方連結用局所領域のサイズ(画素: 3 <= area_size <= 20 )
[in] area_overlap 連結用局所領域の重なり(画素: area_overlap <= area_size / 2 )
[in] min_clust_elem クラスタに属するエッジ点の個数の最小値( 2 <= min_clust_elem
[in] mode 再連結処理(0:無効、0以外:有効)
[out] *ppedge_clust 抽出した曲線の情報(クラスタ)の配列(初期値は NULL を指定)
[out] pclust_num 抽出した曲線の個数(初期値は0を指定)
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM パラメータ異常
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
処理結果例:
以下に処理結果例を示します。 左から、入力画像、エッジ画像、処理結果画像になります。 処理結果画像において、エッジ点を連結して生成された曲線が色ごとに表示されています。 なお、構成しているエッジ点の個数が少ない曲線は、表示していません。
fie_edge_connect_result.png

使用例
// エラー処理は省略しているので注意して下さい。
#include "fie.h"
#include "oal_aloc.h"


VOID edge_connecting()
{
    // 入力画像
    FHANDLE himg = NULL;
    // 出力エッジ画像
    FHANDLE hdst = NULL;

    //入力画像の幅と高さ
    INT width, height;

    // 2次元エッジ抽出用
    F_DEDGE             *pedges = NULL;
    INT                 edge_num = 0;
    F_EDGE_CORR_PARAMS  params;
    DPNT_T              offset;

    // エッジ点群連結用
    F_EDGE_CLUST    *pclust = NULL;
    INT             clust_num = 0;

    DOUBLE  weight, threshold1, threshold2;
    INT     area_size, area_overlap, min_clust_elem, mode;

    // 連結して生成された曲線描画用
    DOUBLE color[12][3] = {
        {   0.0,   0.0, 255.0 },
        {   0.0,   0.0, 128.0 },
        {   0.0, 255.0,   0.0 },
        { 255.0, 255.0,   0.0 },
        { 255.0, 165.0,   0.0 },
        { 255.0,   0.0,   0.0 },
        { 255.0, 192.0, 203.0 },
        { 176.0,  48.0,  96.0 },
        {   0.0, 255.0, 255.0 },
        { 160.0,  32.0, 240.0 },
        { 255.0,   0.0, 255.0 },
        {   0.0, 100.0,   0.0 },
    };
    INT i, j;
    
    // 入力画像の読み込み
    // 適当な画像を読み込んでください
    fnFIE_load_png( "sample1.png", &himg, F_COLOR_IMG_TYPE_UC8 );

    //入力画像の幅と高さを取得
    width = fnFIE_img_get_width( himg );
    height = fnFIE_img_get_height( himg );

    // 入力画像を3チャネル化した出力画像を確保
    hdst = fnFIE_img_root_alloc( F_IMG_UC8, 3, width, height );
    fnFIE_img_clear( hdst, 0 ); 

    // 2次元エッジ抽出(相関エッジ)用パラメータの設定
    params.width            = 5;
    params.height           = 5;
    params.sigmoid_k        = 1.0;
    params.var_threshold    = 25.0;
    params.mag_threshold    = 160;
    params.nms_length       = 6;
    offset.x = offset.y     = 0.0;

    // 2次元エッジ抽出(相関エッジ)
    fnFIE_edge_corr_subpix( himg, NULL, &params, F_EDGE_FEAT_DIRECT, F_BORDER_CONTINUOUS, offset, &pedges, &edge_num );

    // エッジ点群の連結用パラメータの設定
    weight          = 0.07;
    threshold1      = 2.0;
    threshold2      = 4.0;
    area_size       = 10;
    area_overlap    = 3;
    min_clust_elem  = 3;
    mode            = 1;

    // エッジ点群の連結
    fnFIE_edge_connecting( pedges, edge_num, weight, threshold1, threshold2, 
                           area_size, area_overlap, min_clust_elem, mode,
                           &pclust, &clust_num );

    // 連結された曲線を色を変えて出力画像上に描画する
    for( i = 0; i < clust_num; i++ ){
        for( j = 0; j < ( pclust[i].num - 1); j++ ){
            DPNT_T start, end;

            start.x = pedges[pclust[i].pindex[j]].x;
            start.y = pedges[pclust[i].pindex[j]].y;
            end.x   = pedges[pclust[i].pindex[j + 1]].x;
            end.y   = pedges[pclust[i].pindex[j + 1]].y;

            // 点と点の間は線分で描画する
            fnFIE_draw_line_seg( hdst, color[i%12], start, end );
        }
    }

    // メモリの解放
    fnFIE_free_edge_clust( pclust, clust_num );
    fnOAL_free( pedges );
    fnFIE_free_object( himg );
    fnFIE_free_object( hdst );
}

INT main()
{
    // FIEライブラリの使用前に必ずコールする必要があります。
    fnFIE_setup();

    edge_connecting();

    // 終了処理
    fnFIE_teardown();

    return 0;
}

参照:
fnFIE_edge_sobel_subpix, fnFIE_edge_corr_subpix, fnFIE_edge_connecting2

INT FVALGAPI fnFIE_free_edge_clust ( F_EDGE_CLUST pedge_clust,
INT  clust_num 
)

エッジ点クラスタ配列の解放

エッジ点クラスタ構造体配列を解放します。

引数:
[in] pedge_clust エッジ点クラスタ配列
[in] clust_num エッジ点クラスタ配列 要素数 ( clust_num >= 0 )
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM パラメータ以上
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー

INT FVALGAPI fnFIE_edge_connecting2 ( const F_DEDGE pedges,
INT  edge_num,
DOUBLE  angle_range,
INT  distance_range,
INT  min_clust_elem,
INT  max_clust_elem,
F_EDGE_CLUST **  ppedge_clust,
INT *  pclust_num 
)

エッジ点の連結

入力されたエッジ点群を連結し、複数の曲線( クラスタ ) を抽出します。

エッジ点の勾配方向に垂直な方向を そのエッジ点の連結方向とし、 各エッジ点が連結方向に向かって連結先となるエッジ点を見つけ連結を行っていくことにより 1 つの曲線を抽出していきます。 勾配方向についての詳細は 総合ドキュメントのエッジ角度 をご参照ください。

fie_edge_connect_2_fig1.png

この時、連結先となるエッジ点は 注目エッジ点の連結方向とパラメータで指定された 探索角度範囲( angle_range )、 探索距離範囲( distance_range) から 下図 のように規定される探索範囲内で見つけられます。
探索角度範囲と探索距離範囲を調整することにより、結果として得られるクラスタの連結状態を調整することができます。

fie_edge_connect_2_fig2.png

探索範囲内のエッジ点については、 注目エッジ点と距離が近いものほど、また探索角度範囲の中心に近いものほど連結先として選ばれやすくなります。
従って下図では C のエッジ位置より B のエッジ位置が、また B のエッジ位置より A のエッジ位置が連結先エッジ点として選ばれやすくなります。

fie_edge_connect_2_fig3.png

クラスタに属するエッジ点個数の制限 ( min_clust_elem, max_clust_elem ) :
クラスタに属するエッジ点の最大/最小個数を指定することにより、出力として得られるクラスタから 極端に短い (構成するエッジ点数が少ない) もの、 または 極端に長い (構成するエッジ点数が多い) ものを除外することが出来ます。
最小個数は min_clust_elem 、最大個数は max_clust_elem により指定します。指定する最大個数は最小個数以上でなくてはなりません。
また、max_clust_elem に負の値を指定した場合 最大個数 は無制限となります。
入力データと出力データについて :
入出力データの形式は 下記のように fnFIE_edge_connecting() と同様となっています。
入力データ( pedges ):
入力されるエッジ点は、 fnFIE_edge_sobel_subpix()fnFIE_edge_corr_subpix() によって 座標以外に勾配方向が求められている必要があります。 そのため、想定する勾配方向の範囲は、 $-\pi$pedges->q$\pi$ (単位:ラジアン) となります。 ただし、勾配方向の範囲は内部でチェックしていません。 範囲外の勾配方向が入力されてもエラーとはなりません。
出力データ( ppedge_clust ):
出力データは、以下に示す条件に従います。 なお、必要のなくなった曲線の情報( ppedge_clust )の配列は、必ず fnFIE_free_edge_clust() で解放してください。
  • 出力データは下図に示すように、 F_EDGE_CLUST の配列となります。 一つの F_EDGE_CLUST が一つの曲線を表しています。
  • 曲線には、開曲線または閉曲線の二種類があります。 閉曲線は、最初に格納されたエッジ点と最後に格納されたエッジ点が同じエッジ点となります。 開曲線は、最初と最後に格納されたエッジ点が異なります。
  • F_EDGE_CLUST に保持されているデータは、エッジ点の座標ではなく、入力されたエッジ点群配列のインデックスとなります。
  • F_EDGE_CLUST 配列の保存順序は処理された順になります。 曲線間の位置関係などに依存しません。

fie_edge_clust.png
推奨パラメータ
パラメータ名 推奨値
angle_range $\pi$ / 2.0
distance_range 5
min_clust_elem 3
max_clust_elem -1
引数:
[in] pedges エッジ点の配列
[in] edge_num エッジ点の個数 ( 2 ≦ edge_num )
[in] angle_range 探索角度範囲 ( 単位: radian , 0 < angle_range$\pi$ )
[in] distance_range 探索距離範囲 ( 単位: pixel , 0 < distance_range )
[in] min_clust_elem クラスタに属するエッジ点個数の最小値 ( 2 ≦ min_clust_elem )
[in] max_clust_elem クラスタに属するエッジ点個数の最大値 ( min_clust_elemmax_clust_elem ,ただし max_clust_elem < 0 とした場合は無制限 )
[out] ppedge_clust 抽出した曲線の情報 ( クラスタ ) の配列 ( 初期値は NULL を指定 )
[out] pclust_num 抽出した曲線の個数
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM パラメータ異常
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
参照:
fnFIE_free_edge_clust

INT FVALGAPI fnFIE_refilter_edge_by_mask ( const F_DEDGE src_edges,
INT  src_edge_num,
FHANDLE  hmask,
INT  mask_mode,
F_DEDGE **  dst_edges,
INT *  dst_edge_num 
)

マスクによる エッジ点群のフィルタリング

入力されたエッジ点群に対して、指定した マスク によるフィルタリングを行い 出力エッジ点群 にコピーし返します。
マスクにはリージョンオブジェクト、または 2値 画像オブジェクトを使用することができます。

リージョンオブジェクトをマスクとして指定した場合、リージョンに含まれる座標を有効座標、リージョンに含まれない座標を 無効座標として扱います。
画像オブジェクトをマスクとして指定した場合、画素値が1の座標を有効座標、画素値が0の座標 及び 画像範囲外の座標を 無効座標として扱います。

マスクモード
マスクされたエッジ点を省くか、残すかを mask_mode にて指定します。
  • mask_mode が 0 の場合、入力エッジ点群の中から 無効座標 のもののみを出力エッジ点群にコピーします。
  • mask_mode が 1 の場合、入力エッジ点群の中から 有効座標 のもののみを出力エッジ点群にコピーします。
  マスクモード 0 マスクモード 1
リージョン
オブジェクト
リージョンに含まれる座標 ×
リージョンに含まれない座標 ×
画像
オブジェクト
画素値1の座標 ×
画素値0の座標
及び画像範囲外の座標
×
○ : 出力エッジ点群にコピーされる.
× : 出力エッジ点群にコピーされない.
画像オブジェクトをマスクとして使用する場合
マスクとして使用する画像オブジェクトは 画像型が F_IMG_BIN であり、チャネル数が 1 でなければいけません。
(画像サイズについての制限はありません)
出力エッジ点 配列
dst_edges は、関数内部で必要なメモリを確保します。メモリを確保した配列を指定しないで下さい。 *dst_edges が NULL で初期化されていない場合は エラーとなります。
dst_edges に返されたメモリを解放する場合は fnOAL_free() を使用して下さい。
また、出力されたエッジ点の数は dst_edge_num に返されます。
出力されたエッジ点の数が 0 である場合には、dst_edges には NULL が返され正常終了します。
引数:
[in] src_edges 入力エッジ点 配列
[in] src_edge_num 入力エッジ点の個数 ( 1 <= src_edge_num )
[in] hmask マスク
  • リージョンオブジェクト
  • 画像オブジェクト ( type:bin / ch:1 )
[in] mask_mode マスクモード
  • 0 : リージョンに含まれるエッジ点を省く.
  • 1 : リージョンに含まれるエッジ点を残す.
[out] dst_edges 出力エッジ点 配列 ( 初期値は NULL を指定 )
[out] dst_edge_num 出力エッジ点の個数
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM 不正なパラメータが渡された
F_ERR_INVALID_OBJECT 不正なマスクが渡された
F_ERR_INVALID_IMAGE マスクとして渡された画像オブジェクトが不正である
F_ERR_NOMEMORY メモリ不足エラー
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
example code:
#include "oal_aloc.h"
#include "fie.h"

/*
 このサンプルコードは入力画像内の特定部分以外をマスクによって削除します。
  入力画像のエッジを取得したい特定部分を覆うようなリージョンを作成し、エッジ検出後にそのリージョンの範囲内のエッジ点のみ取得しなおします。
  出力結果として、マスクなしエッジ結果画像、マスクありエッジ結果画像を示します。
*/

INT fnSMP_edge_filter_by_mask() {
    INT                 ret = F_ERR_UNKNOWN;       //デフォルトは不明なエラー
    FHANDLE             hin = NULL;                //処理対象画像用のハンドル
    FHANDLE             hout = NULL;               //出力画像用のハンドル
    FHANDLE             hout2 = NULL;              //出力画像用のハンドル
    FHANDLE             hreg = NULL;               //リージョン用のハンドル
    INT                 width, height;             //入力画像サイズ
    INT                 channels;                  //入力画像のチャンネル数
    DPNT_T              dCenter;                   //楕円形リージョンの中心のX座標
    DOUBLE              dLong_r;                   //楕円形リージョンの長い半径
    DOUBLE              dShort_r;                  //楕円形リージョンの短い半径
    DOUBLE              dTheta;                    //楕円回転角(ラジアン)
    F_EDGE_SOBEL_PARAMS params;                    //エッジ検出用パラメータ
    UINT                feat_mode;                 //エッジ検出用パラメータ
    INT                 e_border_mode;             //エッジ検出用パラメータ
    DPNT_T              offset;                    //エッジ検出用パラメータ
    F_DEDGE*            edges = NULL;              //エッジ点配列の作業用ポインタ
    INT                 edge_num = 0;              //検出されたエッジ点の個数  
    DPNT_T              pnt;                       //エッジ点描画用座標
    DOUBLE              val;                       //塗りつぶし用濃度値
    F_DEDGE*            dst_edges = NULL;          //マスク処理後エッジ用ポインタ
    INT                 dst_edge_num = 0;          //マスク処理後エッジ数
    INT                 i = 0;


    //パラメータの設定
    //出力画像のファイル名はパラメータで事前に決定できます。
    //for fnFIE_load_img_file
    CHAR input_name[100] = "input.png";       //処理対象入力ファイル名
    //for fnFIE_save_png
    CHAR mask_name[100] = "mask.png";           //マスク画像のファイル名
    CHAR output_name[100] = "output1.png";        //マスクなしエッジ画像のファイル名
    CHAR output_name2[100] = "output2.png";       //マスク処理後エッジ画像のファイル名
    //for fnFIE_create_region_ellipse  
    dCenter.x = 180;                            //楕円形リージョンの中心のX座標 
    dCenter.y = 125;                            //楕円形リージョンの中心のY座標 
    dLong_r = 60;                               //楕円形リージョンの長半径
    dShort_r = 30;                              //楕円形リージョンの短半径
    dTheta = 0;                                 //楕円回転角(ラジアン)
    //for fnFIE_edge_sobel_subpix                                   
    params.mag_threshold = 100;                 // 強度しきい値                    
    params.nms_length = 1;                      // 非極大抑制のフィルタ片幅        
    feat_mode = F_EDGE_FEAT_MAG_SUM;            // 勾配方向、強度データ保持の指定  
    e_border_mode = F_BORDER_NONE;              // ボーダー処理
    offset.x = offset.y = 0.0;                  // オフセット量
    //for fnFIE_draw_point
    val = 255.0;                                //エッジ点の濃度値

    // 入力画像の読み込み
    ret = fnFIE_load_img_file(input_name, &hin, F_COLOR_IMG_TYPE_UC8);
    if (ret != F_ERR_NONE) goto EXIT;

    //出力先の確保のため入力画像のサイズ取得
    ret = fnFIE_img_get_params(hin, &channels, NULL, NULL, &width, &height);
    if (ret != F_ERR_NONE) goto EXIT;
    
    //入力画像はch数が1のみのものに限定
    if (channels != 1) {
        ret = F_ERR_INVALID_IMAGE;
        goto EXIT;
    }

    //マスク画像のメモリ確保
    hmsk = fnFIE_img_root_alloc(F_IMG_UC8, channels, width, height);
    if (hmsk == NULL) {
        ret = F_ERR_NOMEMORY; goto EXIT;
    }
    ret = fnFIE_img_clear(hmsk, 255);//白く塗りつぶす
    if (ret != F_ERR_NONE) goto EXIT;

    //出力画像のメモリ確保
    hout = fnFIE_img_root_alloc(F_IMG_UC8, channels, width, height);
    if (hout == NULL) {
        ret = F_ERR_NOMEMORY; goto EXIT;
    }

    ret = fnFIE_img_clear(hout, 0);//黒く塗りつぶす
    if (ret != F_ERR_NONE) goto EXIT;

    hout2 = fnFIE_img_root_alloc(F_IMG_UC8, channels, width, height);
    if (hout2 == NULL) {
        ret = F_ERR_NOMEMORY; goto EXIT;
    }

    ret = fnFIE_img_clear(hout2, 0);//黒く塗りつぶす
    if (ret != F_ERR_NONE) goto EXIT;

    //リージョン生成
    hreg = fnFIE_create_region_ellipse(dCenter, dLong_r, dShort_r, dTheta);
    if (hreg == NULL) {
        ret = F_ERR_NOMEMORY; goto EXIT;
    }

    //入力画像全体にエッジ検出を実行
    ret = fnFIE_edge_sobel_subpix(hin, NULL, &params, feat_mode, e_border_mode, offset, &edges, &edge_num);
    if (ret != F_ERR_NONE) goto EXIT;

    //エッジ点の描画
    for (i = 0; i < edge_num; i++) {
        pnt.x = edges[i].x;
        pnt.y = edges[i].y;
        fnFIE_draw_point(hout, &val, pnt);
    }

    //エッジ点をリージョンの範囲内のみに限定
    ret = fnFIE_refilter_edge_by_mask(edges, edge_num, hreg, 1, &dst_edges, &dst_edge_num);
    if (ret != F_ERR_NONE) goto EXIT;

    //エッジ点の描画
    for (i = 0; i < dst_edge_num; i++) {
        pnt.x = dst_edges[i].x;
        pnt.y = dst_edges[i].y;
        fnFIE_draw_point(hout2, &val, pnt);
    }

    //結果画像の保存
    ret = fnFIE_save_png(output_name, hout, -1);
    if (ret != F_ERR_NONE) goto EXIT;

    ret = fnFIE_save_png(output_name2, hout2, -1);
    if (ret != F_ERR_NONE) goto EXIT;

EXIT:

    //メモリの開放
    fnOAL_free(edges);
    fnOAL_free(dst_edges);
    fnFIE_free_object(hin);
    fnFIE_free_object(hreg);
    fnFIE_free_object(hmsk);
    fnFIE_free_object(hout);
    fnFIE_free_object(hout2);


    return ret;
}

INT main() {
    INT ret = F_ERR_UNKNOWN; //デフォルトは不明なエラー

    // FIEライブラリの使用前に必ずコールする必要がある
    fnFIE_setup();

    ret = fnSMP_edge_filter_by_mask();

    // 終了処理
    fnFIE_teardown();

    return ret;
}

処理結果例:
以下はexample codeを実行した場合の出力結果です。
fie_refilter_edge_by_mask_input.png

(a)

fie_refilter_edge_by_mask_mask.png

(b)

fie_refilter_edge_by_mask_output1.png

(c)

fie_refilter_edge_by_mask_output2.png

(d)

(a)入力画像。
(b)参考画像。エッジを取得する範囲を示す。
(c)出力画像。画像全体に対してエッジ検出を行った結果。
(d)出力画像。エッジ点を(b)画像に示す範囲にのみに限定した結果。

INT FVALGAPI fnFIE_refilter_edge_by_clust ( const F_DEDGE src_edges,
INT  src_edge_num,
const F_EDGE_CLUST edge_clust,
INT  edge_clust_num,
const INT *  clust_idx,
INT  clust_idx_num,
F_DEDGE **  dst_edges,
INT *  dst_edge_num 
)

クラスタ情報による エッジ点群のフィルタリング

入力されたエッジ点群の中から、指定した エッジ点クラスタ に含まれるもののみを 出力エッジ点群 にコピーし返します。

エッジ点クラスタ配列
edge_clust に渡す エッジ点クラスタ配列 には、入力エッジ点配列 ( src_edges ) に対して実行した fnFIE_edge_connecting()fnFIE_edge_connecting2() 等の結果として得られる F_EDGE_CLUST(クラスタに属するエッジ点のインデックスが格納された構造体) の配列を使用して下さい。
edge_clust に格納されている エッジ点のインデックスが、入力エッジ点 配列( src_edges )の要素数の範囲外であった場合 エラー となります。
処理対象エッジ点クラスタのインデックス配列
エッジ点クラスタ配列( edge_clust ) に含まれる複数の クラスタ の中から 処理対象としたい クラスタ のインデックスを 配列 clust_idx に格納し指定して下さい。
このとき 配列 clust_idx に 同じ インデックス が 複数個 含まれていても、そのインデックスのクラスタが 処理対象となるのは 1 度のみとなります。
配列 clust_idx に エッジ点クラスタ配列 の要素数の範囲外となるインデックスが含まれていた場合は エラー となります。
また clust_idx に NULL を指定した場合、エッジ点クラスタ配列 の中の全ての クラスタ が処理対象となります。
出力エッジ点 配列
dst_edges は、関数内部で必要なメモリを確保します。メモリを確保した配列を指定しないで下さい。 *dst_edges が NULL で初期化されていない場合は エラーとなります。
dst_edges に返されたメモリを解放する場合は fnOAL_free() を使用して下さい。
また、出力されたエッジ点の数は dst_edge_num に返されます。
クラスタが閉曲線である場合
処理対象エッジ点クラスタが閉曲線、つまり 最初に格納されているエッジ点と最後に格納されているエッジ点が同じである場合、 最後に格納されているエッジ点は 出力エッジ点 に含まれません。
引数:
[in] src_edges 入力エッジ点 配列
[in] src_edge_num 入力エッジ点の個数 ( 1 <= src_edge_num )
[in] edge_clust エッジ点クラスタ配列
[in] edge_clust_num エッジ点クラスタ配列 要素数
[in] clust_idx 処理対象エッジ点クラスタのインデックス配列
( clust_idx = NULL とした場合は全 クラスタ を処理対象とする )
[in] clust_idx_num 処理対象エッジ点クラスタのインデックス配列 要素数
[out] dst_edges 出力エッジ点 配列 ( 初期値は NULL を指定 )
[out] dst_edge_num 出力エッジ点の個数
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM 不正なパラメータが渡された
F_ERR_NOMEMORY メモリ不足エラー
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー


Documentation copyright © 2009-2024 FAST Corporation.
Generated on Fri Aug 9 16:38:48 2024 for FIEライブラリ by doxygen 1.5.6-FASTSP-p2