2次元エッジ検出
[画像フィルタ]


データ構造

struct  F_EDGE_SOBEL_PARAMS
 Sobelエッジ用パラメータ構造体 [詳細]
struct  F_EDGE_CORR_MAX_PARAMS
 強度上限付相関エッジ用パラメータ構造体 [詳細]
struct  F_EDGE_SOBEL_MAX_PARAMS
 強度上限付Sobelエッジ用パラメータ構造体 [詳細]
struct  F_EDGE_GROOVE_PARAMS
 細線エッジ用パラメータ構造体 [詳細]
struct  F_EDGE
 勾配方向、強度付エッジ点構造体(整数型) [詳細]
struct  F_DEDGE
 勾配方向、強度付エッジ点構造体(浮動小数点型) [詳細]
struct  F_EDGE_CORR_PARAMS
 相関エッジ用パラメータ構造体 [詳細]

マクロ定義

#define F_EDGE_FEAT_NONE   0x00000000
 エッジ勾配方向、強度保持指定フラグ エッジの勾配方向、強度供に取得しない
#define F_EDGE_FEAT_MAG_SUM   0x00000001
 エッジ勾配方向、強度保持指定フラグ エッジの強度をX方向微分とY方向微分の絶対値和として取得する
#define F_EDGE_FEAT_MAG_SQRT   0x00000002
 エッジ勾配方向、強度保持指定フラグ エッジの強度をX方向微分とY方向微分のユークリッド距離として取得する
#define F_EDGE_FEAT_DIRECT   0x00000004
 エッジ勾配方向、強度保持指定フラグ エッジの勾配方向を取得する

関数

INT FVALGAPI fnFIE_edge_canny (FHANDLE hImgSrc, FHANDLE hImgOut, INT iTSwitch, DOUBLE dTHigh, DOUBLE dTLow, DOUBLE dSigma, UINT uiMinLen)
 Canny 法によるエッジ検出
INT FVALGAPI fnFIE_nms_canny (FHANDLE hMagX, FHANDLE hMagY, FHANDLE hMag, DOUBLE dTLow, DOUBLE dTHigh, USHORT *ushpTLow, USHORT *ushpTHigh)
 非極大値の抑制(Canny 法によるエッジ検出で利用)
INT FVALGAPI fnFIE_nms (FHANDLE hMagX, FHANDLE hMagY, FHANDLE hMag, DOUBLE dThresh)
 非極大値の抑制(エッジ勾配を利用)
INT FVALGAPI fnFIE_nms_simple (FHANDLE hSrc, FHANDLE hTar, INT iBrdMod, DOUBLE dBrdVal)
 非極大値の抑制 単純
INT FVALGAPI fnFIE_edge_binary_boundary (FHANDLE hsrc, INT smooth_size, DPNT_T offset, F_DEDGE **edges, INT *edge_num)
 領域の境界点列を利用したエッジ検出
INT FVALGAPI fnFIE_edge_corr (FHANDLE hsrc, FHANDLE hmag, const F_EDGE_CORR_PARAMS *params, UINT feat_mode, INT border_mode, PNT_T offset, F_EDGE **edges, INT *edge_num)
 相関エッジフィルタを利用したエッジ検出
INT FVALGAPI fnFIE_edge_corr_subpix (FHANDLE hsrc, FHANDLE hmag, const F_EDGE_CORR_PARAMS *params, UINT feat_mode, INT border_mode, DPNT_T offset, F_DEDGE **edges, INT *edge_num)
 相関エッジフィルタを利用したエッジ検出(サブピクセル精度)
INT FVALGAPI fnFIE_edge_sobel (FHANDLE hsrc, FHANDLE hmag, const F_EDGE_SOBEL_PARAMS *params, UINT feat_mode, INT border_mode, PNT_T offset, F_EDGE **edges, INT *edge_num)
 ソーベルフィルタを利用したエッジ検出
INT FVALGAPI fnFIE_edge_sobel_subpix (FHANDLE hsrc, FHANDLE hmag, const F_EDGE_SOBEL_PARAMS *params, UINT feat_mode, INT border_mode, DPNT_T offset, F_DEDGE **edges, INT *edge_num)
 ソーベルフィルタを利用したエッジ検出(サブピクセル精度)
INT FVALGAPI fnFIE_img_get_points_bin (const FHANDLE hsrc, INT color, INT max_pnt_num, PNT_T *pnts, INT *pnt_num)
 2値画像からの点データ取得
INT FVALGAPI fnFIE_img_get_points_gray (const FHANDLE hsrc, DOUBLE tlow, DOUBLE thigh, INT max_pnt_num, PNT_T *pnts, INT *pnt_num)
 濃淡画像からの点データ列取得
INT FVALGAPI fnFIE_nms_dir (FHANDLE hmagx, FHANDLE hmagy, FHANDLE hthin, DOUBLE thresh)
 非極大値の抑制(エッジ勾配方向を利用)

関数

INT FVALGAPI fnFIE_edge_canny ( FHANDLE  hImgSrc,
FHANDLE  hImgOut,
INT  iTSwitch,
DOUBLE  dTHigh,
DOUBLE  dTLow,
DOUBLE  dSigma,
UINT  uiMinLen 
)

Canny 法によるエッジ検出

Canny 法によるエッジ検出を行います。 Canny 法によるエッジ検出は、望ましい評価基準として、以下の3つの点を考慮しています。

  • 実際のエッジを検出しそこねる可能性が低く、かつエッジではない点や線をエッジとする確率が低いこと。
  • エッジとして検出した線や点が、真のエッジの中心の近くにあること。
  • 1つのエッジに対して、唯一のエッジ検出結果が与えられること。
本関数は内部で、 fnFIE_gaussian_1Dfilter_conv() , fnFIE_gaussian_1Dfilter_iir(), fnFIE_nms_canny() , fnFIE_hysteresis_rle_uf() を使用しています。 出力は、 UC8 型の画像オブジェクトとなり、エッジ点は 255 , 背景は 0 です。

本関数では、ヒステリシス特性で利用される2つの閾値は、2つの異なるモードで与えることがきます。 1つは、両方の閾値を 1.0 より小さく与えることです。 例えば、 dTLow = 0.2 、 dTHigh = 0.7 として与えた場合、 dTLow よって関数内部で計算された閾値より小さいエッジ勾配強度が、全体の画素の 20% であることを示します。 さらに、 70% の画素は、エッジ勾配強度が dTHigh によって計算された閾値より小さいことを示します。 もう一方のモードは、直接、取得したいエッジ勾配強度の値を2つの閾値で指定します。 指定する閾値は、 2^16 - 1 以下の値で指定してください。

引数:
[in] hImgSrc 入力画像 ( type: uc8 )
[out] hImgOut 出力画像 ( type: uc8 )
[in] iTSwitch 閾値のタイプ指定
  • iTSwitch = 0 :2つの閾値である割合が 0 < threshold < 1
  • iTSwitch = 1 :2つの閾値が任意の値
[in] dTLow 閾値の下限
[in] dTHigh 閾値の上限
  • ( iTSwitch == 0 && 0 < dTLow < 1 && 0 < dTHigh < 1 ) の場合
    指定する閾値は割合です
  • ( iTSwitch == 1 && dTLow >= 0 && dTHigh > 0 ) の場合
    指定する閾値は任意の値です
    2つの閾値ともに 2^16 より小さい値を指定してください
  • ( iTSwitch == 0 && dTLow == 0 && dTHigh == 0 ) の場合
    dTHigh(0.7) 、 dTLow(0.28)のデフォルト値が指定されます
[in] dSigma ガウシアンマスクのσ
[in] uiMinLen エッジの最小の長さ
この値より小さい孤立したエッジはノイズと判定して削除されます
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM 不正なパラメータが渡された
  • 不正な値の閾値
  • dSigma < 0.6
  • 画像の幅、または高さが (INT)(6 * dSigma + 2) より小さい
F_ERR_INVALID_IMAGE 不正な画像が渡された
  • 入力画像と出力画像のサイズが異なる
  • 画像の幅、または高さが3より小さい
  • 画像オブジェクトではないハンドルが渡された
  • 画像のチャネルが1ではない
  • 画像サイズが ( 3 * dSigma + 1 ) * 2 より小さい
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
参考文献:
  • 1. Canny, J. "A computational approach to edge detection", IEEE Trans. PAMI, 1986, Vol. 8(6), 679-698.
  • 2. Parker, J. "Algorithms for Image Processing and Computer Vision", John Wiley & Sons, 1996, Chap. 1: Advanced Edge-Detection Techniques, pp. 1-62
  • 3. 高木幹雄・下田陽久, "新編 画像解析ハンドブック", 東京大学出版会, 2004, pp.1238-1239
処理結果例:
floppy1.png

入力画像

fie_canny_edge.png

処理結果画像

INT FVALGAPI fnFIE_nms_canny ( FHANDLE  hMagX,
FHANDLE  hMagY,
FHANDLE  hMag,
DOUBLE  dTLow,
DOUBLE  dTHigh,
USHORT *  ushpTLow,
USHORT *  ushpTHigh 
)

非極大値の抑制(Canny 法によるエッジ検出で利用)

非極大抑制は、画像に対して1次微分を施した後に実行されます。 注目画素の勾配を選択させた2つの隣接した画素の勾配と比較します。 注目画素の勾配が隣接した画素の勾配より大きかった場合、 局所的な最大値となり勾配強度は保持されて後の処理に利用されます。 そうでない場合は、0が設定されます。

非極大抑制は、細線化のような効果がありますが、勾配方向を考慮しているため 処理結果は必ずしも1画素の幅の線になるとは限りません。

本関数では、出力画像の周囲1画素は0になります。 また、 hMagXhMagY で与えられたx方向とy方向のエッジ勾配強度は、 互いに絶対値演算が計算されて、エッジ勾配強度として処理に利用されます。

入力パラメータの dTLowdTHigh は 0.0〜1.0 の範囲で指定してください。 これらのパラメータは、計算時に使用される閾値で画素の割合を表しています。 つまり、すべての画素と特徴量が閾値より小さい画素との割合を表しています。 例えば、 dTHigh=0.7 が与えられた場合、エッジ勾配強度が dTHigh から計算される上限閾値 より小さな値の画素は、画像全体の 70% であることを示します。 また、 dTLow=0.2 が与えられた場合、エッジ勾配強度が dTLow から計算される下限閾値 より小さな値の画素は、画像全体の 20% であることを示します。 dTLowdTHigh が共に0.0の場合は、デフォルトの dTHight=0.7 、 dTLow=0.35 が与えられます。

入力画像、出力画像は下記の条件をすべて満たしている必要が有ります。

  • サイズ(幅・高さ)が等しい
  • 縦横サイズは3画素以上
  • チャネル数が等しい
  • チャネル数は1
  • 入力画像の型はF_IMG_S16
  • 出力画像の型はF_IMG_US16
引数:
[in] hMagX X方向のエッジ勾配強度画像 ( type: s16 )
[in] hMagY Y方向のエッジ勾配強度画像 ( type: s16 )
[out] hMag エッジ勾配強度画像 (type: us16)
[in] dTLow ピクセル数の下限方向の割合を決定するための閾値
[in] dTHigh ピクセル数の上限方向の割合を決定するための閾値
  • 0 < dTLow < 1.0 && 0 < dTHigh < 1.0
  • dTLow < dTHigh or dTLow == dTHigh == 0.0
[out] ushpTLow dTLow から得られた下限閾値
[out] ushpTHigh dTHigh から得られた上限閾値
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM 不正なパラメータが渡された
  • ( dTHigh <= dTLow && ( dTHigh != 0.0 && dTLow != 0.0 ) ) or ( dTHigh >= 1 || dTLow >= 1 || dTHigh < 0 || dTLow < 0 )
F_ERR_INVALID_IMAGE 不正な画像が渡された
  • 各画像のサイズが違う(縦横サイズ、チャネル数)
  • 不正な画像が渡された
  • 画像横縦サイズはいずれが3以下
  • 画像のチャネル数は1以上
F_ERR_NOMEMORY バッファーメモリ配分失敗
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー

INT FVALGAPI fnFIE_nms ( FHANDLE  hMagX,
FHANDLE  hMagY,
FHANDLE  hMag,
DOUBLE  dThresh 
)

非極大値の抑制(エッジ勾配を利用)

非極大抑制は、画像に対して1次微分を施した後に実行されます。 注目画素の勾配を、勾配方向に隣接した2つの画素の勾配と比較します。 注目画素の勾配が隣接した画素の勾配より大きかった場合、 局所的な最大値となり勾配強度は保持されて後の処理に利用されます。 そうでない場合は、0が設定されます。

非極大抑制は、細線化のような効果があります。 しかしながら、勾配方向を考慮しており、処理結果は必ずしも1画素の幅の線になるとは限りません。

なお本関数では、出力画像の周囲1画素は0になります。 また、 hMagXhMagY で与えられたx方向とy方向のエッジ勾配強度は、 互いに絶対値演算がなされて、エッジ勾配強度として処理に利用されます。

dThresh は勾配の非常に小さい値を取り除くために利用されます。 1以上の値を与えてください。

引数:
[in] hMagX X方向のエッジ勾配強度画像 (type: s16, double )
[in] hMagY Y方向のエッジ勾配強度画像 (type: s16, double )
[out] hMag エッジ勾配強度画像 (type: us16, double )
  • hMagXhMagY が S16 型の場合、 hMag は US16 型 または DOUBLE 型となる
  • hMagXhMagY が DOUBLE 型の場合、 hMag は DOUBLE 型となる
[in] dThresh 非常に小さい勾配を取り除くための閾値
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM dThresh < 0
F_ERR_INVALID_IMAGE 各画像のサイズが違う、不正な画像が渡された
画像サイズの横縦いずれかが3以下, 或いは (2^16 - 1) 以上
F_ERR_NOMEMORY バッファーメモリ配分失敗
F_ERR_UNKNOWN 原因不明なエラー
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー

INT FVALGAPI fnFIE_nms_simple ( FHANDLE  hSrc,
FHANDLE  hTar,
INT  iBrdMod,
DOUBLE  dBrdVal 
)

非極大値の抑制 単純

3x3の領域中、注目画素が周囲の画素よりも小さかったら濃度を零にします。等しかったり大きかったら何もしません。 通常のNMSは線の接続性を見るため、それよりも多めに線を分断します。 ボーダー処理モード iBrdMod に F_BORDER_NONE 指定した場合は、境界上の画素の濃度値は0になります。

入力画像と出力画像は下記の条件をすべて満たしている必要が有ります。

  • サイズ(幅・高さ)が等しい
  • チャネル数が等しい
  • 入力画像の型はF_IMG_UC8, F_IMG_S16, F_IMG_US16, F_IMG_DOUBLE のいずれか

引数:
[in] hSrc 入力画像 (uc8, s16, us16, double)
[out] hTar 出力画像 (uc8, s16, us16, double)
[in] iBrdMod ボーダー処理モード
  • F_BORDER_NONE ボーダー処理無し
  • F_BORDER_ZERO 0埋めモード
  • F_BORDER_VALUE 一定値モード
  • F_BORDER_CONTINUOUS 端延長モード
  • F_BORDER_REPEAT 繰り返しモード
  • F_BORDER_MIRROR1 反転モード1
  • F_BORDER_MIRROR2 反転モード2
[in] dBrdVal ボーダー濃度値
iBrdMod がF_BORDER_VALUEの場合のみ使用されます。 その他のモードの場合は、この値は無視されます。
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_PARAM 不正なボーダー処理モードが渡された
F_ERR_INVALID_IMAGE 各画像のサイズが違う、不正な画像が渡された
F_ERROR_NOMEMORY メモリー不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー

INT FVALGAPI fnFIE_edge_binary_boundary ( FHANDLE  hsrc,
INT  smooth_size,
DPNT_T  offset,
F_DEDGE **  edges,
INT *  edge_num 
)

領域の境界点列を利用したエッジ検出

サブピクセル精度で、領域の境界点列を利用してエッジを検出します。

本関数はリージョンや2値画像からFPMに使用できるエッジを検出するために使用できます。 fnFIE_fpm_import_alloc()fnFIE_fpm_feature_import_alloc() に検出されたエッジを入力して使用してください。

入力オブジェクト hsrc には以下の2つのオブジェクトのうち、どちらかを使用できます。

  • リージョンオブジェクト
  • 2値画像の画像オブジェクト
移動平均フィルタサイズ smooth_size:
境界点列に対する平滑化の強さを決定するパラメータです。 1以上の奇数を指定します。
大きな値を設定することによりエッジ点の位置と角度を安定化できますが、領域形状との差異が生じます。
3から7程度の値を指定することを推奨します。
1つの連結した領域がごく小さい場合、過剰な平滑化を避けるため、フィルタサイズは自動的に縮小されます。 具体的には、1つの領域の境界点列の点の数を n とし (n > 1)、 n が smooth_size * 2 より小さい場合、その領域に対するフィルタサイズは n ÷ 2 を超えない最大の奇数となります。
オフセット量 offset:
取得したエッジの座標に、指定したオフセット量を加えます。
取得エッジ:
本関数では検出されたエッジ点を保存するための配列のメモリ確保の方法を選択することができます。
  • 関数内部での自動確保
  • 関数外部でのユーザが任意に確保
*edges が NULL で初期化されている場合は、 *edges は内部でメモリが自動的に確保されます。 検出されたエッジ個数は、 edge_num を参照してください。 *edges が不要になった後は、 fnOAL_free() をコールして確保したメモリを解放してください。
*edges が NULL で初期化されていない場合は、本関数内部でメモリ確保しません。 メモリを確保した配列を用意してください。 edge_num に確保したメモリの個数を入力してください(1以上)。 ただし、 edge_num はエッジを検出後、検出されたエッジ点個数に上書きされます。 検出されたエッジ点個数は入力された edge_num 以下となります。 入力された edge_num を超える分のエッジ点は出力されません。
取得エッジの座標範囲:
入力オブジェクト hsrc が画像の場合、取得エッジの範囲は以下の通りとなります。
  • 0 <= edges->x <= width - 1
  • 0 <= edges->y <= height - 1
入力オブジェクト hsrc がリージョンの場合、取得エッジの範囲は以下の通りとなります。
  • xmin <= edges->x <= xmax
  • ymin <= edges->y <= ymax
    ただし、xmin, ymin, xmax, ymaxは fnFIE_region_get_xyrange() にて取得される領域のx、y座標の最大値と最小値です。
取得エッジの勾配方向、強度範囲:
取得エッジに保持されている強度は不明(mag=0)とします。
取得エッジに保持されている勾配方向は、以下の範囲で取得されます。 勾配方向についての詳細は 総合ドキュメントのエッジ角度 をご参照ください。 なお、入力オブジェクト hsrc がリージョンの場合、領域内を白、領域外を黒とみなして角度を取得します。
  • 勾配方向:$-\pi$edges->q$\pi$ (単位:ラジアン)
引数:
[in] hsrc 入力FIEオブジェクト
  • リージョン
  • 2値画像ハンドル( type : bin, ch : 1 )
[in] smooth_size 移動平均フィルタサイズ
[in] offset オフセット量
[out] edges 取得したエッジ
[in,out] edge_num 取得したエッジ数
戻り値:
F_ERR_NONE 正常終了
F_ERR_NOMEMORY メモリ不足
F_ERR_INVALID_IMAGE 不正な画像が渡された
F_ERR_INVALID_OBJECT 不正なオブジェクトが渡された
F_ERR_INVALID_PARAM パラメータ不正
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー

              

使用例:
#include "fie.h"    
#include "oal_aloc.h"
#include <stdio.h>

//OSによる分岐
#ifdef _WIN32           //windows
#include <windows.h>
#include <time.h>
#else                   //linux
#include <sys/time.h>
#endif

#define RESULT_N 20     //マッチングの最大検出数

/*
    fnFIE_edge_binary_boundaryを用いた高速サーチ

    このサンプルでは通常のFPMより処理時間の短い手法として
    fnFIE_edge_binary_boundaryを用いたFPMを紹介するものです
    流れとして同一の画像、同一のパタンを用いてそれぞれの手法で
    FPMを行い、それぞれの処理時間を提示します


*/

//時間計測用関数
DOUBLE time_record()
{
//OSによる分岐
#ifdef _WIN32        //windows
    DOUBLE TIME;
    FILETIME time;
    ULARGE_INTEGER t;

    GetSystemTimePreciseAsFileTime(&time);

    t.LowPart = time.dwLowDateTime;
    t.HighPart = time.dwHighDateTime;

    TIME = (DOUBLE)t.QuadPart / 10000;

    return TIME;
#else                //linux
    struct timeval time;
    DOUBLE x,y;
    DOUBLE TIME;

    gettimeofday(&time, NULL);

    x = (DOUBLE)time.tv_sec;
    y = (DOUBLE)time.tv_usec;

    TIME = x*1000 + y/1000;

    return TIME;
#endif
}

VOID sample_fpm(FHANDLE hImage, FHANDLE hptn)
{
    INT i = 0;

    FHANDLE hfpm = NULL;                    // FPMオブジェクト用ハンドル

    F_FPM_FEATURE       feature_param;      // 特徴量抽出を行う際のパラメータ設定用共用体 
    F_FPM_MATCH         matching_param;     // マッチングを行う際のパラメータ設定用構造体
    F_FPM_AREASCORE     areascore_param;    // 領域スコア再計算を行う際のパラメータ設定用構造体

    enum f_fpm_mode matching_mode;          // マッチングモードの指定用
    enum f_fpm_featedge method;             // 特徴量を取得する際のエッジ取得方法の指定用
    F_EDGE_SOBEL_PARAMS sobel;              // ソーベルエッジ検出用パラメータ

    BOX_T   win;                            // マッチングエリア指定の矩形設定用
    DPNT_T  offset;                         // マッチング回答オフセット値  
    INT  result_num;                        // マッチング結果の個数
    F_SEARCH_RESULT result[RESULT_N];       // マッチング結果の格納用配列

    INT image_width, image_height;          // 入力画像の幅、高さ
    INT ptn_width, ptn_height;              //パタンの幅、高さ
    INT err_code;                           // エラーコード取得用
    
    DOUBLE start, end;                      //時間記録用

    //入力画像のパラメータ獲得
    fnFIE_img_get_params(hImage, NULL, NULL, NULL, &image_width, &image_height);
    fnFIE_img_get_params(hptn, NULL, NULL, NULL, &ptn_width, &ptn_height);

    // サーチの手法設定
    matching_mode = F_FPM_NORMAL_MODE;  // マッチングモードは通常モード
    method = F_FPM_SOBEL_EDGE;          // エッジ取得方法はソーベルエッジ

    // サーチのマッチングパラメータ設定
    matching_param.require_result_num = RESULT_N;
    matching_param.min_angle = -45;
    matching_param.max_angle = 45;
    matching_param.min_scale = 100;
    matching_param.max_scale = 100;
    matching_param.polarity = F_FPM_SAME_POLARITY;
    matching_param.coarse_highcomp_threshold = 50;
    matching_param.coarse_lowcomp_threshold = 60;
    matching_param.coarse_err_wide = 1;
    matching_param.coarse_comp_rate = 3;
    matching_param.refine_execute = TRUE;
    matching_param.refine_err_wide = 1;
    matching_param.refine_threshold = 70;

    //領域スコア再計算パラメータ設定
    areascore_param.err_wide = 1;
    areascore_param.err_wide_tx = 0.5;
    areascore_param.err_wide_ty = 0.5;
    areascore_param.err_wide_tq = 0.5;
    areascore_param.err_wide_ts = 0.5;
    areascore_param.noise_weight = 0.5;
    areascore_param.threshold = 70;

    //ソーベルエッジパラメータ設定
    sobel.nms_length = 1;
    sobel.mag_threshold = 40;
    feature_param.sobel_edge = sobel;

    //マスターパタン生成用のパラメータ設定 
    offset.x = ptn_width / 2.0;
    offset.y = ptn_height / 2.0;

    //マスターパタン登録
    hfpm = fnFIE_fpm_alloc(hptn, NULL, offset, matching_mode, method, &feature_param, &err_code);

    //サーチ範囲設定
    win.st.x = 0;
    win.st.y = 0;
    win.ed.x = image_width - 1;
    win.ed.y = image_height - 1;

    //処理開始時間計測
    start = time_record();

    //サーチ実行
    fnFIE_fpm_matching(hfpm, hImage, NULL, win, method, &feature_param, &matching_param, &areascore_param, result, &result_num);

    //処理終了時間計測
    end = time_record();

    // 実行結果をコンソール出力
    printf("normal FPM\n");
    for (i = 0; i < result_num; i++)
    {
        printf("[x, y]=[%8.3f,%8.3f]  theta=[%8.3f] scale=[%8.3f]  score=[%3d] \n", result[i].x, result[i].y, result[i].q, result[i].s, result[i].score);
    }
    printf("time:%.3fms\n\n", end-start);

    //オブジェクトの解放
    fnFIE_free_object(hfpm);
}

VOID sample_fast_fpm(FHANDLE hImage, FHANDLE hptn)
{
    INT i ,j;
    INT num = 0;
    DOUBLE start, end;                         //時間計測用
         
    FHANDLE hImageptn = NULL;                  // 入力画像のチャイルド画像設定用ハンドル
    FHANDLE hbin = NULL;                       // 二値画像用ハンドル
    FHANDLE hbinptn = NULL;                    // 二値画像のチャイルド画像設定用ハンドル
    FHANDLE hfpm = NULL;                       // FPMオブジェクト用ハンドル
    FHANDLE h_edge_fpm = NULL;                 // FPMオブジェクト用ハンドル
    FHANDLE fpm_feat_obj = NULL;               // FPMオブジェクト用ハンドル
    FHANDLE hreg = NULL;                       // FPMオブジェクト用ハンドル

    F_FPM_MATCH         matching_param;        // マッチングを行う際のパラメータ設定用構造体
    F_FPM_AREASCORE     areascore_param;       // 領域スコア再計算を行う際のパラメータ設定用構造体

    enum f_fpm_mode matching_mode;             // マッチングモードの指定用

    BOX_T   win;                               // マッチングエリア指定の矩形設定用
    DPNT_T  offset;                            // マッチング回答オフセット値  

    INT image_width, image_height;             // 入力画像の幅、高さ
    INT ptn_width, ptn_height;                 // パタンの幅、高さ


    FHANDLE measure_result;                    //ブロブ解析結果ハンドル 
    F_MEASURE_PARAMS param;                    //ブロブ解析用パラメータセット 
    PNT_T orgin;                               //原点座標オフセット 
    UINT blobnum;                              //ブロブ数
    UINT* fil_blobnum = NULL;                  //フィルタ後のブロブ番号配列
    F_MEASURE_FILTER_RANGE filters[10];        //ブロブ取得条件フィルタ配列

    F_DEDGE* edges = NULL;                      //エッジデータ
    INT  edge_num;                              //エッジデータ数
    F_DEDGE* cild_edges = NULL;                 //パタン用エッジデータ
    INT  cild_edge_num;                         //パタン用エッジデータ数
    DPNT_T  edge_offset;                        //エッジ検出用座標
    INT  edge_result_num;                       // エッジ検出後のマッチング結果の個数
    F_SEARCH_RESULT edge_result[RESULT_N];      // 各マッチング結果の格納用配列
    F_SEARCH_RESULT total_result[RESULT_N];     // 統合したマッチング結果の格納用配列



    //入力画像のパラメータ獲得
    fnFIE_img_get_params(hImage, NULL, NULL, NULL, &image_width, &image_height);
    fnFIE_img_get_params(hptn, NULL, NULL, NULL, &ptn_width, &ptn_height);

    // サーチの手法設定
    matching_mode = F_FPM_NORMAL_MODE;  // マッチングモードは通常モード

    // サーチのマッチングパラメータ設定
    matching_param.require_result_num = RESULT_N;
    matching_param.min_angle = -45;
    matching_param.max_angle = 45;
    matching_param.min_scale = 100;
    matching_param.max_scale = 100;
    matching_param.polarity = F_FPM_SAME_POLARITY;
    matching_param.coarse_highcomp_threshold = 50;
    matching_param.coarse_lowcomp_threshold = 60;
    matching_param.coarse_err_wide = 1;
    matching_param.coarse_comp_rate = 3;
    matching_param.refine_execute = TRUE;
    matching_param.refine_err_wide = 1;
    matching_param.refine_threshold = 70;
    
    //領域スコア再計算パラメータ設定
    areascore_param.err_wide = 1;
    areascore_param.err_wide_tx = 0.5;
    areascore_param.err_wide_ty = 0.5;
    areascore_param.err_wide_tq = 0.5;
    areascore_param.err_wide_ts = 0.5;
    areascore_param.noise_weight = 0.5;
    areascore_param.threshold = 70;


    //マスターパタン生成用のパラメータ設定 
    offset.x = ptn_width / 2.0; 
    offset.y = ptn_height / 2.0;

    //サーチ範囲設定
    win.st.x = 0;
    win.st.y = 0;
    win.ed.x = image_width - 1;
    win.ed.y = image_height - 1;

    // 座標原点の指定
    orgin.x = 0; orgin.y = 0;

    //ブロブ解析用パラメータ設定
    memset(&param, 0, sizeof(F_MEASURE_PARAMS));
    param.color_mode = F_MEASURE_WHITEFG_BLACKBG;
    param.neighborhood = 8;

    //パタン画像の二値化
    hbinptn = fnFIE_img_root_alloc(F_IMG_BIN, 1, ptn_width, ptn_height);
    fnFIE_binarize(hptn, hbinptn, 200);

    //マスターパタン登録 
    edge_offset.x = 0;
    edge_offset.y = 0;
    fnFIE_edge_binary_boundary(hbinptn, 3, edge_offset, &cild_edges, &cild_edge_num);
    h_edge_fpm = fnFIE_fpm_import_alloc(cild_edges, cild_edge_num, hImageptn, offset, matching_mode, NULL);

    //処理開始時間計測
    start = time_record();

    //サーチ対象画像の二値化
    hbin = fnFIE_img_root_alloc(F_IMG_BIN, 1, image_width, image_height);
    fnFIE_binarize(hImage, hbin, 200);

    // 二値ブローブ解析の実行
    measure_result = fnFIE_measure_execute(hbin, orgin, &param, NULL);
     
    //条件に合うブロブを取得
    //マスターパタンを解析して得た値に±αした値を条件としている
    filters[0].type = F_FEATURE_AREA;
    filters[0].min = 480;
    filters[0].max = 580;
    filters[1].type = F_FEATURE_RECT2AREA;
    filters[1].min = 950;
    filters[1].max = 1050;
    filters[2].type = F_FEATURE_FERET_MIN;
    filters[2].min = 0;
    filters[2].max = 30;
    fnFIE_measure_get_list(measure_result, filters, 3, &fil_blobnum, &blobnum);

    //ブロブごとにサーチ
    for (i = 0; i < blobnum; i++)
    {
        hreg = fnFIE_measure_get_region(measure_result, fil_blobnum[i], NULL);
        fnFIE_edge_binary_boundary(hreg, 3, edge_offset, &edges, &edge_num);
        fpm_feat_obj = fnFIE_fpm_feature_import_alloc(edges, edge_num, image_width, image_height, matching_mode, NULL);
        fnFIE_fpm_matching_feature(h_edge_fpm, fpm_feat_obj, NULL, win, &matching_param, edge_result, &edge_result_num);
        //結果をコピーして纏める
        for (j = 0; j < edge_result_num; j++)
        {
            total_result[num] = edge_result[j];
            num++;
            //numが最大検出数を超えたら終了
            if (num > RESULT_N)break;
        }

        //オブジェクトの開放と初期化
        fnFIE_free_object(hreg);              hreg = NULL;
        fnFIE_free_object(fpm_feat_obj);  fpm_feat_obj = NULL;
        fnOAL_free(edges);                   edges = NULL;

        //numが最大検出数を超えたら終了
        if (num > RESULT_N)break;
    }

    //処理終了時間計測
    end = time_record();

    //実行結果をコンソール出力
    printf("FPM using fnFIE_edge_binary_boundary\n");
    for (i = 0; i < num; i++)
    {
        printf("[x, y]=[%8.3f,%8.3f]  theta=[%8.3f] scale=[%8.3f]  score=[%3d] \n", total_result[i].x, total_result[i].y, total_result[i].q, total_result[i].s, total_result[i].score);
    }
    printf("time:%.3fms\n\n", end-start);

    //加工後の画像の保存
    fnFIE_save_bmp("bin.bmp", hbin);
    fnFIE_save_bmp("binptn.bmp", hbinptn);

    //オブジェクトの解放
    fnFIE_free_object(hreg);       
    fnFIE_free_object(fpm_feat_obj);  
    fnFIE_free_object(hbin);
    fnFIE_free_object(hfpm);
    fnFIE_free_object(hbinptn);
    fnFIE_free_object(h_edge_fpm);
    fnFIE_free_object(hImageptn);
    fnFIE_free_object(measure_result);
    fnOAL_free(edges);
    fnOAL_free(cild_edges);
    fnOAL_free(fil_blobnum);

}


INT main(VOID)
{
    //ライブラリのセットアップ
    fnFIE_setup();

    FHANDLE hImage = NULL;           // 入力画像用ハンドル
    FHANDLE hptn = NULL;             // FPMオブジェクト用ハンドル


    //画像の読み込み
    fnFIE_load_bmp("smp_fast_fpm.bmp", &hImage, F_COLOR_IMG_TYPE_UC8);
    fnFIE_load_bmp("ptn.bmp", &hptn, F_COLOR_IMG_TYPE_UC8);

    //サーチの実行処理
    sample_fpm(hImage,hptn);        //通常版
    sample_fast_fpm(hImage,hptn);   //高速版

    //オブジェクト解放
    fnFIE_free_object(hptn);
    fnFIE_free_object(hImage);

    //ライブラリの終了処理
    fnFIE_teardown();



    return 0;
}

fie_edge_binary_boundary_smp_obj.png

(a)

fie_edge_binary_boundary_smp_refilter.png

(b)

fie_edge_binary_boundary_smp_result.png

(c)

(a)サーチ対象画像。このサンプルコードでは『1』の文字をサーチしている。
(b)選別したブロブを可視化した画像。条件を細かく設定することにより事前にサーチ対象外は省いている。
(c)実行時に検出した座標を描画した画像。本関数の有無で検出結果自体には差は出ないが処理速度は平均2〜3倍程度早くなっている

INT FVALGAPI fnFIE_edge_corr ( FHANDLE  hsrc,
FHANDLE  hmag,
const F_EDGE_CORR_PARAMS params,
UINT  feat_mode,
INT  border_mode,
PNT_T  offset,
F_EDGE **  edges,
INT *  edge_num 
)

相関エッジフィルタを利用したエッジ検出

相関エッジフィルタを利用してエッジを検出します。 エッジ情報を細線化後、特徴量を抽出します。 ノイズやボケ、シェーディングなどの悪条件に比較的強い傾向がありますが、 ソーベルより処理時間が掛かり、パラメータ調整にも熟練が必要です。

なお、本関数ではエッジをサブピクセル精度で取得はしません。 サブピクセル精度でエッジを取得したい場合は、 fnFIE_edge_corr_subpix() を使用してください。

エッジ検出のためのパラメータ:
下表のパラメータがあります。パラメータの意味や決定方法については F_EDGE_CORR_PARAMS 構造体を参照してください。
名前推奨値値域
相関エッジフィルタの幅( width ) 133 ≦ width ≦ 255の奇数, heightwidth
相関エッジフィルタの高さ( height ) 51 ≦ height ≦ 255の奇数, heightwidth
シグモイド係数( sigmoid_k ) 1.00 < sigmoid_k
分散しきい値( var_threshold ) UC8型の場合は250 < var_threshold ≦上限値。上限値は画像型に依存
強度しきい値( mag_threshold ) 1600 ≦ mag_threshold ≦ 255
非極大抑制のフィルタ片幅( nms_length ) 6 (= ( width - 1) / 2) 1 ≦ nms_length
勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード:
エッジ点構造体( F_EDGE )に勾配方向、強度データを保持するかどうかを指定するためのフラグです。 ビットフラグで指定します。 以下のマクロ定義を組み合わせて使用してください。
  • F_EDGE_FEAT_NONE : 勾配方向、強度共に保持しない
  • F_EDGE_FEAT_MAG_SUM : 強度( 絶対値和: $Gxy_{(i,j)} = |Gx_{(i,j)}|+|Gy_{(i,j)}|$ )を保持
  • F_EDGE_FEAT_MAG_SQRT : 強度( ユークリッド距離: $Gsqrt_{(i,j)} = \sqrt{Gx_{(i,j)}^2+Gy_{(i,j)}^2}$ )を保持
  • F_EDGE_FEAT_DIRECT : 勾配方向( $\arctan{ \left( Gy_{(i,j)} , Gx_{(i,j)} \right)}$ )を保持
ここで、 $ Gx_{(i,j)} , Gy_{(i,j)} $ は、x方向微分画像、y方向微分画像に対する座標( x , y ) での微分値となります。

本フラグの指定により、以下の通りにデータが保持されます。
  • F_FEAT_EDGE_MAG_…が指定されており、F_EDGE_FEAT_DIRECTが指定されていない場合は、強度のみが保持されます。 勾配方向には0が代入されます。
  • F_EDGE_FEAT_DIRECTが指定されており、F_EDGE_FEAT_MAG_…が指定されていない場合は、勾配方向のみが保持されます。 強度には0が代入されます。
  • F_EDGE_FEAT_DIRECTとF_EDGE_FEAT_MAG_…が共に指定されている場合は、勾配方向と強度の両方が保持されます。
  • F_EDGE_FEAT_NONEが指定された場合は、勾配方向、強度共に0が代入されます。
  • エッジ検出実行時は、F_EDGE_FEAT_MAG_SUM と F_EDGE_FEAT_MAG_SQRT を同時に強度を指定することはできません。
本マクロ定義以外のビットのフラグがオン(1)になっている場合はエラーとなります。
オフセット量:
取得したエッジの座標に、指定したオフセット量を加えます。 edgesxy にのみ反映されます。 エッジ強度画像( hmag )には反映されません。
エッジ強度画像:
feat_mode で指定したエッジの強度を画像として出力します。 必要がない場合は、 hmag を NULLで指定してください。 feat_mode で強度が指定されていなくて、 hmag がNULLでない場合は、エラーとなります。 なお、エッジ強度画像が、画素タイプが F_IMG_US16 、チャネル数、サイズは入力画像と同じである必要があります。

また、取得される強度は、理論上の最大値が US16_MAX(65535)となるように正規化されています。 実際に取得されたエッジ点の強度の最大値ではありません。
取得エッジ:
edges は、関数内部で必要なメモリを確保します。 メモリを確保した配列を指定しないでください。 また、 *edges がNULLで初期化されていない場合は、エラーとなります。 確保されたメモリは、 fnOAL_free() で解放してください。
取得エッジの座標範囲:
取得エッジの範囲は以下の通りとなります。
  • 0 ≦ edges->x ≦ width - 1
  • 0 ≦ edges->y ≦ height - 1
取得エッジの勾配方向、強度範囲:
取得エッジに保持されている勾配方向、強度は、以下の範囲で取得されます。 fnFIE_edge_corr_subpix() とは、勾配方向の単位や、強度の範囲が異なりますので注意してください。 勾配方向についての詳細は 総合ドキュメントのエッジ角度 をご参照ください。
  • 勾配方向:-180 ≦ edges->q ≦ 180 (単位:度)
  • 強度:0 ≦ edges->mag ≦ 16384
入力画像のサイズ:
画像内でエッジが取得可能な領域は、以下のパラメータによって決定されます。
  • 相関エッジフィルタの幅( parans.width )
  • 非極大抑制のフィルタ片幅( params.nms_length )
ボーダーモードなしで本関数を実行した場合、画像の周囲[ (INT) parans.width / 2 + params.nms_length]画素は、エッジが取得できません。 そのため、入力画像の幅、高さは[ parans.width + params.nms_length * 2]以上でない場合は、エラーとなります。
覚え書き:
入力画像の型が F_IMG_UC8 かつステップ数が8の倍数でない場合、処理速度が遅くなります。 注意してください。
引数:
[in] hsrc 入力画像(type:uc8, s16, us16, double / ch:1)
[out] hmag エッジ強度画像(type:us16 / ch:1)
[in] params エッジ検出のための各種パラメータ
[in] feat_mode 勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード
[in] border_mode ボーダーモード
  • F_BORDER_NONE ボーダー処理無し
  • F_BORDER_CONTINUOUS 端延長モード
[in] offset オフセット量
[out] edges 取得したエッジ
[out] edge_num 取得したエッジ数
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_IMAGE 不正な画像オブジェクトが渡された
F_ERR_INVALID_PARAM 不正なパラメータが渡された
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
参考文献:
  • 保刈久明, シグモイド関数との相関によるエッジ抽出, ビジョン技術の実利用ワークショップ (ViEW2006) 講演論文集, I-6, 2006

処理結果例:
処理のために指定したパラメータは以下の通りとなります。
  • params.width = 5
  • params.height = 3
  • params.var_threshold = 25
  • params.sigmoid_k = 1
  • params.mag_threshold = 100
  • params.nms_length = 1

なお処理結果画像は、実際に取得したエッジ点を入力画像に描画した画像です。
floppy1.png

入力画像

fie_edge2d_corr.png

処理結果画像

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

INT main()
{
    INT i;

    // 入力画像
    FHANDLE hsrc = NULL;

    // パラメータ
    F_EDGE_CORR_PARAMS params;
    UINT feat_mode;
    INT border_mode;
    PNT_T offset;

    // 取得されるエッジ
    F_EDGE * pedges = NULL;

    // 取得されるエッジの数
    INT edge_num;

    // FIEライブラリの初期化処理
    fnFIE_setup();

    // 入力画像をファイルから読み込む
    fnFIE_load_bmp("src_img.bmp", &hsrc, F_COLOR_IMG_TYPE_UC8);

    // パラメータの設定
    params.width = 5;           // 相関エッジフィルタの幅
    params.height= 3;           // 相関エッジフィルタの高さ
    params.sigmoid_k = 1.0;     // シグモイド係数
    params.var_threshold = 25;  // 分散しきい値
    params.mag_threshold = 100; // 強度しきい値
    params.nms_length = 1;      // 非極大抑制のフィルタ片幅

    feat_mode = F_EDGE_FEAT_NONE;   // 勾配方向、強度データ保持の指定
    border_mode = F_BORDER_NONE;    // ボーダー処理
    offset.x = offset.y = 0;        // オフセット量

    // 相関エッジフィルタを利用したエッジ検出の実行
    fnFIE_edge_corr(hsrc, NULL, 
                  &params, feat_mode, border_mode, offset,
                  &pedges, &edge_num);

    // 取得したエッジ点を入力画像上にプロットし、ファイルへ保存する
    for(i=0; i<edge_num; i++){
        fnFIE_img_set_dens(hsrc, 0, pedges[i].x, pedges[i].y, 255);
    }

    fnFIE_save_bmp("dst_img.bmp", hsrc);

    // 入力画像の解放
    fnFIE_free_object(hsrc);

    // 取得したエッジは fnOAL_free関数により解放する
    fnOAL_free(pedges);

    // FIEライブラリの終了処理
    fnFIE_teardown();

    return 0;
}


INT FVALGAPI fnFIE_edge_corr_subpix ( FHANDLE  hsrc,
FHANDLE  hmag,
const F_EDGE_CORR_PARAMS params,
UINT  feat_mode,
INT  border_mode,
DPNT_T  offset,
F_DEDGE **  edges,
INT *  edge_num 
)

相関エッジフィルタを利用したエッジ検出(サブピクセル精度)

サブピクセル精度で、相関エッジフィルタを利用してエッジを検出します。 エッジ情報を細線化後、特徴量を抽出します。 ノイズやボケ、シェーディングなどの悪条件に比較的強い傾向がありますが、 ソーベルより処理時間が掛かり、パラメータ調整にも熟練が必要です。

エッジ検出のためのパラメータ:
下表のパラメータがあります。パラメータの意味や決定方法については F_EDGE_CORR_PARAMS 構造体を参照してください。
名前推奨値値域
相関エッジフィルタの幅( width ) 133 ≦ width ≦ 255の奇数, heightwidth
相関エッジフィルタの高さ( height ) 51 ≦ height ≦ 255の奇数, heightwidth
シグモイド係数( sigmoid_k ) 1.00 < sigmoid_k
分散しきい値( var_threshold ) UC8型の場合は250 < var_threshold ≦上限値。上限値は画像型に依存
強度しきい値( mag_threshold ) 1600 ≦ mag_threshold ≦ 255
非極大抑制のフィルタ片幅( nms_length ) 6 (= ( width - 1) / 2) 1 ≦ nms_length
勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード:
エッジ点構造体( F_DEDGE )に勾配方向、強度データを保持するかどうかを指定するためのフラグです。 ビットフラグで指定します。 以下のマクロ定義を組み合わせて使用してください。
  • F_EDGE_FEAT_NONE : 勾配方向、強度共に保持しない
  • F_EDGE_FEAT_MAG_SUM : 強度( 絶対値和: $Gxy_{(i,j)} = |Gx_{(i,j)}|+|Gy_{(i,j)}|$ )を保持
  • F_EDGE_FEAT_MAG_SQRT : 強度( ユークリッド距離: $Gsqrt_{(i,j)} = \sqrt{Gx_{(i,j)}^2+Gy_{(i,j)}^2}$ )を保持
  • F_EDGE_FEAT_DIRECT : 勾配方向( $\arctan{ \left( Gy_{(i,j)}^{'} , Gx_{(i,j)}^{'} \right)}$ )を保持
ここで、 $ Gx_{(i,j)} , Gy_{(i,j)} $ は、x方向微分画像、y方向微分画像に対する座標( x , y ) での微分値となります。 なお、 本関数では勾配方向は $ Gx_{(i,j)} , Gy_{(i,j)} $ により計算されていません。 勾配方向の精度向上を目的として、 $ Gx_{(i,j)} , Gy_{(i,j)} $ の周囲画像を利用した補正計算により求められた $ Gx_{(i,j)}^{'} , Gy_{(i,j)}^{'} $ により計算されます。 ただし、強度の計算には $ Gx_{(i,j)}^{'} , Gy_{(i,j)}^{'} $ ではなく、 $ Gx_{(i,j)} , Gy_{(i,j)} $ がそのまま利用されます。

本フラグの指定により、以下の通りにデータが保持されます。
  • F_EDGE_FEAT_MAG_…が指定されており、F_EDGE_FEAT_DIRECTが指定されていない場合は、強度のみが保持されます。 勾配方向には0が代入されます。
  • F_EDGE_FEAT_DIRECTが指定されており、F_EDGE_FEAT_MAG_…が指定されていない場合は、勾配方向のみが保持されます。 強度には0が代入されます。
  • F_EDGE_FEAT_DIRECTとF_EDGE_FEAT_MAG_…が共に指定されている場合は、勾配方向と強度の両方が保持されます。
  • F_EDGE_FEAT_NONEが指定された場合は、勾配方向、強度共に0が代入されます。
  • エッジ検出実行時は、F_EDGE_FEAT_MAG_SUM と F_EDGE_FEAT_MAG_SQRT を同時に強度を指定することはできません。
本マクロ定義以外のビットのフラグがオン(1)になっている場合はエラーとなります。
オフセット量:
取得したエッジの座標に、指定したオフセット量を加えます。 edgesxy にのみ反映されます。 エッジ強度画像( hmag )には反映されません。
エッジ強度画像:
feat_mode で指定したエッジの強度を画像として出力します。 必要がない場合は、 hmag を NULLで指定してください。 feat_mode で強度が指定されていなくて、 hmag がNULLでない場合は、エラーとなります。 なお、エッジ強度画像が、画素タイプが F_IMG_US16 、チャネル数、サイズは入力画像と同じである必要があります。

また、取得される強度は、理論上の最大値が US16_MAX(65535)となるように正規化されています。 実際に取得されたエッジ点の強度の最大値ではありません。
取得エッジ:
edges は、関数内部で必要なメモリを確保します。 メモリを確保した配列を指定しないでください。 また、 *edges がNULLで初期化されていない場合は、エラーとなります。 確保されたメモリは、 fnOAL_free() で解放してください。
取得エッジの座標範囲:
取得エッジの範囲は以下の通りとなります。
  • -0.5 < edges->x < width - 0.5
  • -0.5 < edges->y < height - 0.5
取得エッジの勾配方向、強度範囲:
取得エッジに保持されている勾配方向、強度は、以下の範囲で取得されます。 fnFIE_edge_corr() とは、勾配方向の単位や、強度の範囲が異なりますので注意してください。 勾配方向についての詳細は 総合ドキュメントのエッジ角度 をご参照ください。
  • 勾配方向:$-\pi$edges->q$\pi$ (単位:ラジアン)
  • 強度:0.0 ≦ edges->mag ≦ 1.0
入力画像のサイズ:
画像内でエッジが取得可能な領域は、以下のパラメータによって決定されます。
  • 相関エッジフィルタの幅( parans.width )
  • 非極大抑制のフィルタ片幅( params.nms_length )
  • エッジの座標点をサブピクセル精度で求めるためのマスクサイズ( 3×3固定 )
ボーダーモードなしで本関数を実行した場合、画像の周囲[ (INT) parans.width / 2 +params.nms_length + 1]画素は、エッジが取得できません。 なお最後に加えた1は、サブピクセル精度で求めるためのマスクの片幅です。 そのため、入力画像の幅、高さは[ parans.width + params.nms_length * 2 + 2]以上でない場合は、エラーとなります。
覚え書き:
入力画像の型が F_IMG_UC8 かつステップ数が8の倍数でない場合、処理速度が遅くなります。 注意してください。
引数:
[in] hsrc 入力画像(type:uc8, s16, us16, double / ch:1)
[out] hmag エッジ強度画像(type:us16 / ch:1)
[in] params エッジ検出のための各種パラメータ
[in] feat_mode 勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード
[in] border_mode ボーダーモード
  • F_BORDER_NONE ボーダー処理無し
  • F_BORDER_CONTINUOUS 端延長モード
[in] offset オフセット量
[out] edges 取得したエッジ
[out] edge_num 取得したエッジ数
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_IMAGE 不正な画像オブジェクトが渡された
F_ERR_INVALID_PARAM 不正なパラメータが渡された
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
参考文献:
  • 保刈久明, シグモイド関数との相関によるエッジ抽出, ビジョン技術の実利用ワークショップ (ViEW2006) 講演論文集, I-6, 2006

処理結果例:
処理のために指定したパラメータは以下の通りとなります。
  • params.width = 5
  • params.height = 3
  • params.var_threshold = 25
  • params.sigmoid_k = 1
  • params.mag_threshold = 100
  • params.nms_length = 1

なお処理結果画像は、実際に取得したエッジ点を入力画像に描画した画像です。
floppy1.png

入力画像

fie_edge2d_corr_subpix.png

処理結果画像

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

INT main()
{
    INT i;

    // 入力画像
    FHANDLE hsrc = NULL;

    // パラメータ
    F_EDGE_CORR_PARAMS params;
    UINT feat_mode;
    INT border_mode;
    DPNT_T offset;

    // 取得されるエッジ
    F_DEDGE * pedges = NULL;

    // 取得されるエッジの数
    INT edge_num;

    // FIEライブラリの初期化処理
    fnFIE_setup();

    // 入力画像をファイルから読み込む
    fnFIE_load_bmp("src_img.bmp", &hsrc, F_COLOR_IMG_TYPE_UC8);

    // パラメータの設定
    params.width = 5;               // 相関エッジフィルタの幅
    params.height= 3;               // 相関エッジフィルタの高さ
    params.sigmoid_k = 1.0;         // シグモイド係数
    params.var_threshold = 25;      // 分散しきい値
    params.mag_threshold = 100;     // 強度しきい値
    params.nms_length = 1;          // 非極大抑制のフィルタ片幅

    feat_mode = F_EDGE_FEAT_NONE;   // 勾配方向、強度データの保持の指定
    border_mode = F_BORDER_NONE;    // ボーダー処理
    offset.x = offset.y = 0.0;      // オフセット量

    // 相関エッジフィルタを利用したエッジ検出(サブピクセル精度)の実行
    fnFIE_edge_corr_subpix(hsrc, NULL,
                        &params, feat_mode, border_mode, offset,
                        &pedges, &edge_num);

    // 取得したエッジ点を入力画像上にプロットし、ファイルへ保存する
    for(i=0; i<edge_num; i++){
        DPNT_T pnt;
        DOUBLE prot_val = 255.0;

        pnt.x = pedges[i].x;
        pnt.y = pedges[i].y;

        fnFIE_draw_point(hsrc, &prot_val, pnt);
    }

    fnFIE_save_bmp("dst_img.bmp", hsrc);

    // 入力画像の解放
    fnFIE_free_object(hsrc);

    // 取得したエッジは fnOAL_free関数により解放する
    fnOAL_free(pedges);

    // FIEライブラリの終了処理
    fnFIE_teardown();

    return 0;
}

INT FVALGAPI fnFIE_edge_sobel ( FHANDLE  hsrc,
FHANDLE  hmag,
const F_EDGE_SOBEL_PARAMS params,
UINT  feat_mode,
INT  border_mode,
PNT_T  offset,
F_EDGE **  edges,
INT *  edge_num 
)

ソーベルフィルタを利用したエッジ検出

ソーベルフィルタ( fnFIE_sobel() )を利用してエッジを検出します。 エッジ情報を細線化後、特徴量を抽出します。 ソーベルフィルタを利用したエッジ検出は、直感的にわかりやすいパラメータで高速で処理が可能ですが、 環境変化に弱く、対象物の焦点ずれ等によるボケが生じた場合に精度の安定性が低い傾向があります。

なお、本関数ではエッジをサブピクセル精度で取得はしません。 サブピクセル精度でエッジを取得したい場合は、 fnFIE_edge_sobel_subpix() を使用してください。

ソーベルフィルタ:
本関数で使用しているフィルタは以下のようになります。
  • X方向
    X方向微分を表す、下記の3x3カーネルにてコンボリューション演算(下式)を行った結果値を出力します。 出力画像の型が符号無し型の場合は、絶対値を取ります。 また、結果値が出力画像の型の最大値を超える場合は、その最大値でサチュレーション処理されます。
    		[-1][0][1]
    		[-2][0][2]
    		[-1][0][1]
    	

    \begin{eqnarray*} Gx_{(i,j)} = &- \{ f_{(i-1,j-1)} + 2 f_{(i-1,j)} + f_{(i-1,j+1)} \} \\ &+ f_{(i+1,j-1)} + 2 f_{(i+1,j)} + f_{(i+1,j+1)} \end{eqnarray*}

  • Y方向
    Y方向微分を表す、下記の3x3カーネルにてコンボリューション演算(下式)を行った結果値を出力します。 出力画像の型が符号無し型の場合は、絶対値を取ります。 また、結果値が出力画像の型の最大値を超える場合は、その最大値で飽和処理されます。
    		[-1][-2][-1]
    		[ 0][ 0][ 0]
    		[ 1][ 2][ 1]
    	

    \begin{eqnarray*} Gy_{(i,j)} = &- \{ f_{(i-1,j-1)} + 2 f_{(i,j-1)} + f_{(i+1,j-1)} \} \\ &+ f_{(i-1,j+1)} + 2 f_{(i,j+1)} + f_{(i+1,j+1)} \end{eqnarray*}

    入力画像に対して、x方向、y方向のソーベルフィルタを施した微分画像をそれぞれ生成し、その後の処理をします。

エッジ検出のためのパラメータ:
強度しきい値( mag_threshold )
  • 推奨値:120
  • エッジの強度に対するしきい値を設定します。 設定値以上のエッジ強度を持つ画素をエッジとみなします。 対象となるマスターパタンと背景のコントラストによって値を調整する必要があります。 (設定範囲: 0 ≦ mag_threshold ≦ 1023 )
非極大抑制のフィルタ片幅( nms_length )
  • 推奨値:1
  • 細線化処理を行う際の幅を設定します。 正しいエッジ位置の近隣に余計なエッジが生じる場合には値を大きくします。 ( 1 ≦ nms_length )
勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード:
エッジ点構造体( F_EDGE )に勾配方向、強度データを保持するかどうかを指定するためのフラグです。 ビットフラグで指定します。 以下のマクロ定義を組み合わせて使用してください。
  • F_EDGE_FEAT_NONE : 勾配方向、強度共に保持しない
  • F_EDGE_FEAT_MAG_SUM : 強度( 絶対値和: $Gxy_{(i,j)} = |Gx_{(i,j)}|+|Gy_{(i,j)}|$ )を保持
  • F_EDGE_FEAT_MAG_SQRT : 強度( ユークリッド距離: $Gsqrt_{(i,j)} = \sqrt{Gx_{(i,j)}^2+Gy_{(i,j)}^2}$ )を保持
  • F_EDGE_FEAT_DIRECT : 勾配方向( $\arctan{ \left( Gy_{(i,j)} , Gx_{(i,j)} \right)}$ )を保持
ここで、 $ Gx_{(i,j)} , Gy_{(i,j)} $ は、x方向微分画像、y方向微分画像に対する座標( x , y ) での微分値となります。 なお、絶対値和は、 fnFIE_sobel() とは異なり2で除算していませんので注意してください。

本フラグの指定により、以下の通りにデータが保持されます。
  • F_EDGE_FEAT_MAG_…が指定されており、F_EDGE_FEAT_DIRECTが指定されていない場合は、強度のみが保持されます。 勾配方向には0が代入されます。
  • F_EDGE_FEAT_DIRECTが指定されており、F_EDGE_FEAT_MAG_…が指定されていない場合は、勾配方向のみが保持されます。 強度には0が代入されます。
  • F_EDGE_FEAT_DIRECTとF_EDGE_FEAT_MAG_…が共に指定されている場合は、勾配方向と強度の両方が保持されます。
  • F_EDGE_FEAT_NONEが指定された場合は、勾配方向、強度共に0が代入されます。
  • エッジ検出実行時は、F_EDGE_FEAT_MAG_SUM と F_EDGE_MAG_SQRT を同時に強度を指定することはできません。
本マクロ定義以外のビットのフラグがオン(1)になっている場合はエラーとなります。
オフセット量:
取得したエッジの座標に、指定したオフセット量を加えます。 edgesxy にのみ反映されます。 エッジ強度画像( hmag )には反映されません。
エッジ強度画像:
feat_mode で指定したエッジの強度を画像として出力します。 必要がない場合は、 hmag を NULLで指定してください。 feat_mode で強度が指定されていなくて、 hmag がNULLでない場合は、エラーとなります。 なお、エッジ強度画像が、画素タイプが F_IMG_US16 、チャネル数、サイズは入力画像と同じである必要があります。

また、取得される強度は、理論上の最大値が US16_MAX(65535)となるように正規化されています。 実際に取得されたエッジ点の強度の最大値ではありません。
取得エッジ:
edges は、関数内部で必要なメモリを確保します。 メモリを確保した配列を指定しないでください。 また、 *edges がNULLで初期化されていない場合は、エラーとなります。 確保されたメモリは、 fnOAL_free() で解放してください。
取得エッジの座標範囲:
取得エッジの範囲は以下の通りとなります。
  • 0 ≦ edges->x ≦ width - 1
  • 0 ≦ edges->y ≦ height - 1
取得エッジの勾配方向、強度範囲:
取得エッジに保持されている勾配方向、強度は、以下の範囲で取得されます。 fnFIE_edge_sobel_subpix() とは、勾配方向の単位や、強度の範囲が異なりますので注意してください。 勾配方向についての詳細は 総合ドキュメントのエッジ角度 をご参照ください。
  • 勾配方向:-180 ≦ edges->q ≦ 180 (単位:度)
  • 強度:0 ≦ edges->mag ≦ 16384
入力画像のサイズ:
画像内でエッジが取得可能な領域は、以下のパラメータによって決定されます。
  • ソーベルフィルタの幅( 3固定 )
  • 非極大抑制のフィルタ片幅( params.nms_length )
ボーダーモードなしで本関数を実行した場合、画像の周囲[1 + params.nms_length]画素は、エッジが取得できません。 なお最初に加えたエッジはソーベルフィルタの片幅です。 そのため、入力画像の幅、高さは[3 + params.nms_length * 2]以上でない場合は、エラーとなります。
引数:
[in] hsrc 入力画像(type:uc8 / ch:1)
[out] hmag エッジ強度画像(type:us16 / ch:1)
[in] params エッジ検出のための各種パラメータ
[in] feat_mode 勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード
[in] border_mode ボーダーモード
  • F_BORDER_NONE ボーダー処理無し
  • F_BORDER_CONTINUOUS 端延長モード
[in] offset オフセット量
[out] edges 取得したエッジ
[out] edge_num 取得したエッジ数
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_IMAGE 不正な画像オブジェクトが渡された
F_ERR_INVALID_PARAM 不正なパラメータが渡された
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
処理結果例:
処理のために指定したパラメータは以下の通りとなります。
  • params.mag_threshold = 40
  • params.nms_length = 1

なお処理結果画像は、実際に取得したエッジ点を入力画像に描画した画像です。
floppy1.png

入力画像

fie_edge2d_sobel.png

処理結果画像

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

INT main()
{
    INT i;

    // 入力画像
    FHANDLE hsrc = NULL;

    // パラメータ
    F_EDGE_SOBEL_PARAMS params;
    UINT feat_mode;
    INT border_mode;
    PNT_T offset;

    // 取得されるエッジ
    F_EDGE * pedges = NULL;

    // 取得されるエッジの数
    INT edge_num;

    // FIEライブラリの初期化処理
    fnFIE_setup();

    // 入力画像をファイルから読み込む
    fnFIE_load_bmp("src_img.bmp", &hsrc, F_COLOR_IMG_TYPE_UC8);

    // パラメータの設定
    params.mag_threshold = 40;  // 強度しきい値
    params.nms_length = 1;      // 非極大抑制のフィルタ片幅

    feat_mode = F_EDGE_FEAT_NONE;   // 勾配方向、強度データ保持の指定
    border_mode = F_BORDER_NONE;    // ボーダー処理
    offset.x = offset.y = 0;        // オフセット量

    // ソーベルフィルタを利用したエッジ検出の実行
    fnFIE_edge_sobel(hsrc, NULL,
                   &params, feat_mode, border_mode, offset,
                   &pedges, &edge_num);

    // 取得したエッジ点を入力画像上にプロットし、ファイルへ保存する
    for(i=0; i<edge_num; i++){
        fnFIE_img_set_dens(hsrc, 0, pedges[i].x, pedges[i].y, 255);
    }

    fnFIE_save_bmp("dst_img.bmp", hsrc);

    // 入力画像の解放
    fnFIE_free_object(hsrc);

    // 取得したエッジは fnOAL_free関数により解放する
    fnOAL_free(pedges);

    // FIEライブラリの終了処理
    fnFIE_teardown();

    return 0;
}

INT FVALGAPI fnFIE_edge_sobel_subpix ( FHANDLE  hsrc,
FHANDLE  hmag,
const F_EDGE_SOBEL_PARAMS params,
UINT  feat_mode,
INT  border_mode,
DPNT_T  offset,
F_DEDGE **  edges,
INT *  edge_num 
)

ソーベルフィルタを利用したエッジ検出(サブピクセル精度)

サブピクセル精度で、ソーベルフィルタ( fnFIE_sobel() )を利用してエッジを検出します。 エッジ情報を細線化後、特徴量を抽出します。 ソーベルフィルタを利用したエッジ検出は、直感的にわかりやすいパラメータで高速で処理が可能ですが、 環境変化に弱く、対象物の焦点ずれ等によるボケが生じた場合に精度の安定性が低い傾向があります。

ソーベルフィルタ:
本関数で使用しているフィルタは以下のようになります。
  • X方向
    X方向微分を表す、下記の3x3カーネルにてコンボリューション演算(下式)を行った結果値を出力します。 出力画像の型が符号無し型の場合は、絶対値を取ります。 また、結果値が出力画像の型の最大値を超える場合は、その最大値でサチュレーション処理されます。
    		[-1][0][1]
    		[-2][0][2]
    		[-1][0][1]
    	

    \begin{eqnarray*} Gx_{(i,j)} = &- \{ f_{(i-1,j-1)} + 2 f_{(i-1,j)} + f_{(i-1,j+1)} \} \\ &+ f_{(i+1,j-1)} + 2 f_{(i+1,j)} + f_{(i+1,j+1)} \end{eqnarray*}

  • Y方向
    Y方向微分を表す、下記の3x3カーネルにてコンボリューション演算(下式)を行った結果値を出力します。 出力画像の型が符号無し型の場合は、絶対値を取ります。 また、結果値が出力画像の型の最大値を超える場合は、その最大値で飽和処理されます。
    		[-1][-2][-1]
    		[ 0][ 0][ 0]
    		[ 1][ 2][ 1]
    	

    \begin{eqnarray*} Gy_{(i,j)} = &- \{ f_{(i-1,j-1)} + 2 f_{(i,j-1)} + f_{(i+1,j-1)} \} \\ &+ f_{(i-1,j+1)} + 2 f_{(i,j+1)} + f_{(i+1,j+1)} \end{eqnarray*}

    入力画像に対して、x方向、y方向のソーベルフィルタを施した微分画像をそれぞれ生成し、その後の処理をします。

エッジ検出のためのパラメータ:
強度しきい値( mag_threshold )
  • 推奨値:120
  • エッジの強度に対するしきい値を設定します。 設定値以上のエッジ強度を持つ画素をエッジとみなします。 対象となるマスターパタンと背景のコントラストによって値を調整する必要があります。 (設定範囲: 0 ≦ mag_threshold ≦ 1023 )
非極大抑制のフィルタ片幅( nms_length )
  • 推奨値:1
  • 細線化処理を行う際の幅を設定します。 正しいエッジ位置の近隣に余計なエッジが生じる場合には値を大きくします。 ( 1 ≦ nms_length )
勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード:
エッジ点構造体( F_EDGE )に勾配方向、強度データを保持するかどうかを指定するためのフラグです。 ビットフラグで指定します。 以下のマクロ定義を組み合わせて使用してください。
  • F_EDGE_FEAT_NONE : 勾配方向、強度共に保持しない
  • F_EDGE_FEAT_MAG_SUM : 強度( 絶対値和: $Gxy_{(i,j)} = |Gx_{(i,j)}|+|Gy_{(i,j)}|$ )を保持
  • F_EDGE_FEAT_MAG_SQRT : 強度( ユークリッド距離: $Gsqrt_{(i,j)} = \sqrt{Gx_{(i,j)}^2+Gy_{(i,j)}^2}$ )を保持
  • F_EDGE_FEAT_DIRECT : 勾配方向( $\arctan{ \left( Gy_{(i,j)} , Gx_{(i,j)} \right)}$ )を保持
ここで、 $ Gx_{(i,j)} , Gy_{(i,j)} $ は、x方向微分画像、y方向微分画像に対する座標( x , y ) での微分値となります。 なお、絶対値和は、 fnFIE_sobel() とは異なり2で除算していませんので注意してください。

本フラグの指定により、以下の通りにデータが保持されます。
  • F_EDGE_FEAT_MAG_…が指定されており、F_EDGE_FEAT_DIRECTが指定されていない場合は、強度のみが保持されます。 勾配方向には0が代入されます。
  • F_EDGE_FEAT_DIRECTが指定されており、F_EDGE_FEAT_MAG_…が指定されていない場合は、勾配方向のみが保持されます。 強度には0が代入されます。
  • F_EDGE_FEAT_DIRECTとF_FEAT_EDGE_MAG_…が共に指定されている場合は、勾配方向と強度の両方が保持されます。
  • F_EDGE_FEAT_NONEが指定された場合は、勾配方向、強度共に0が代入されます。
  • エッジ検出実行時は、F_EDGE_FEAT_MAG_SUM と F_EDGE_FEAT_MAG_SQRT を同時に強度を指定することはできません。
本マクロ定義以外のビットのフラグがオン(1)になっている場合はエラーとなります。
オフセット量:
取得したエッジの座標に、指定したオフセット量を加えます。 edgesxy にのみ反映されます。 エッジ強度画像( hmag )には反映されません。
エッジ強度画像:
feat_mode で指定したエッジの強度を画像として出力します。 必要がない場合は、 hmag を NULLで指定してください。 feat_mode で強度が指定されていなくて、 hmag がNULLでない場合は、エラーとなります。 なお、エッジ強度画像が、画素タイプが F_IMG_US16 、チャネル数、サイズは入力画像と同じである必要があります。

また、取得される強度は、理論上の最大値が US16_MAX(65535)となるように正規化されています。 実際に取得されたエッジ点の強度の最大値ではありません。
取得エッジ:
edges は、関数内部で必要なメモリを確保します。 メモリを確保した配列を指定しないでください。 また、 *edge がNULLで初期化されていない場合は、エラーとなります。 確保されたメモリは、 fnOAL_free() で解放してください。
取得エッジの座標範囲:
取得エッジの範囲は以下の通りとなります。
  • -0.5 < edge->x < width - 0.5
  • -0.5 < edge->y < height - 0.5
取得エッジの勾配方向、強度範囲:
取得エッジに保持されている勾配方向、強度は、以下の範囲で取得されます。 fnFIE_edge_sobel() とは、勾配方向の単位や、強度の範囲が異なりますので注意してください。 勾配方向についての詳細は 総合ドキュメントのエッジ角度 をご参照ください。
  • 勾配方向:$-\pi$edges->q$\pi$ (単位:ラジアン)
  • 強度:0.0 ≦ edges->mag ≦ 1.0
入力画像のサイズ:
画像内でエッジが取得可能な領域は、以下のパラメータによって決定されます。
  • ソーベルフィルタの幅( 3固定 )
  • 非極大抑制のフィルタ片幅( params.nms_length )
  • エッジの座標点をサブピクセル精度で求めるためのマスクサイズ( 3×3固定 )
ボーダーモードなしで本関数を実行した場合、画像の周囲[1 + params.nms_length + 1]画素は、エッジが取得できません。 なお最初に加えたエッジはソーベルフィルタの片幅、最後に加えた1はサブピクセル精度で求めるためのマスクの片幅です。 そのため、入力画像の幅、高さは[3 + params.nms_length * 2 + 2]以上でない場合は、エラーとなります。
引数:
[in] hsrc 入力画像(type:uc8 / ch:1)
[out] hmag エッジ強度画像(type:us16 / ch:1)
[in] params エッジ検出のための各種パラメータ
[in] feat_mode 勾配方向、強度付きエッジ点構造体に保持するデータを指定するモード
[in] border_mode ボーダーモード
  • F_BORDER_NONE ボーダー処理無し
  • F_BORDER_CONTINUOUS 端延長モード
[in] offset オフセット量
[out] edges 取得したエッジ
[out] edge_num 取得したエッジ数
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_IMAGE 不正な画像オブジェクトが渡された
F_ERR_INVALID_PARAM 不正なパラメータが渡された
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
処理結果例:
処理のために指定したパラメータは以下の通りとなります。
  • params.mag_threshold = 40
  • params.nms_length = 1

なお処理結果画像は、実際に取得したエッジ点を入力画像に描画した画像です。
floppy1.png

入力画像

fie_edge2d_sobel_subpix.png

処理結果画像

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

INT main()
{
    INT i;

    // 入力画像
    FHANDLE hsrc = NULL;

    // パラメータ
    F_EDGE_SOBEL_PARAMS params;
    UINT feat_mode;
    INT border_mode;
    DPNT_T offset;

    // 取得されるエッジ
    F_DEDGE * pedges = NULL;

    // 取得されるエッジの数
    INT edge_num;

    // FIEライブラリの初期化処理
    fnFIE_setup();

    // 入力画像をファイルから読み込む
    fnFIE_load_bmp("src_img.bmp", &hsrc, F_COLOR_IMG_TYPE_UC8);

    // パラメータの設定
    params.mag_threshold = 40;  // 強度しきい値
    params.nms_length = 1;      // 非極大抑制のフィルタ片幅

    feat_mode = F_EDGE_FEAT_NONE;   // 勾配方向、強度データ保持の指定
    border_mode = F_BORDER_NONE;    // ボーダー処理
    offset.x = offset.y = 0.0;      // オフセット量

    // ソーベルフィルタを利用したエッジ検出(サブピクセル精度)の実行
    fnFIE_edge_sobel_subpix(hsrc, NULL,
                         &params, feat_mode, border_mode, offset,
                         &pedges, &edge_num);

    // 取得したエッジ点を入力画像上にプロットし、ファイルへ保存する
    for(i=0; i<edge_num; i++){
        DPNT_T pnt;
        DOUBLE prot_val = 255.0;

        pnt.x = pedges[i].x;
        pnt.y = pedges[i].y;

        fnFIE_draw_point(hsrc, &prot_val, pnt);
    }

    fnFIE_save_bmp("dst_img.bmp", hsrc);

    // 入力画像の解放
    fnFIE_free_object(hsrc);

    // 取得したエッジは fnOAL_free関数により解放する
    fnOAL_free(pedges);

    // FIEライブラリの終了処理
    fnFIE_teardown();

    return 0;
}

INT FVALGAPI fnFIE_img_get_points_bin ( const FHANDLE  hsrc,
INT  color,
INT  max_pnt_num,
PNT_T pnts,
INT *  pnt_num 
)

2値画像からの点データ取得

2値画像から指定色の画素を点データとして取得します。 本関数の結果として得られるデータはラスタ走査順序データとなります。

点データの数が引数で指定された最大数に達した場合は処理を中断します。 ただし、この場合は正常終了となります。

引数:
[in] hsrc 入力画像( type:bin / ch:1 )
[in] color 対象エリア色
  • 0:黒
  • 1:白
[in] max_pnt_num 点データの最大数
[out] pnts 点データ格納バッファ( sizeof(PNT_T) * max_pnt_num byte 必要 )
[out] pnt_num 取得された点数(0以上)
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_IMAGE 不正な画像オブジェクトが渡された
F_ERR_INVALID_PARAM 不正なパラメータが渡された
  • pnts または pnt_num がNULL
  • max_pnt_num が0以下
  • color が0または1ではない
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー

INT FVALGAPI fnFIE_img_get_points_gray ( const FHANDLE  hsrc,
DOUBLE  tlow,
DOUBLE  thigh,
INT  max_pnt_num,
PNT_T pnts,
INT *  pnt_num 
)

濃淡画像からの点データ列取得

濃淡画像から指定範囲内の濃度値をもつ画素を点データとして取得します。 本関数の結果として得られるデータはラスタ走査順序データとなります。

濃度値の範囲は tlow ≦ (濃度値) ≦ thigh とします。 画像が整数型の場合、 tlow および thigh は単純キャストで整数に変換されます。 tlow および thigh が対象となる画素タイプの濃度値範囲を超えていた場合は、サチュレーション処理が行われます。

点データの数が引数で指定された最大数に達した場合は処理を中断します。 ただし、この場合は正常終了となります。

引数:
[in] hsrc 入力画像( type:uc8,s16,us16,double / ch:1 )
[in] tlow 2値化閾値の下限
[in] thigh 2値化閾値の上限
[in] max_pnt_num 点データの最大数
[out] pnts 点データ格納バッファ( sizeof(PNT_T) * max_pnt_num byte 必要 )
[out] pnt_num 取得された点数(0以上)
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_IMAGE 不正な画像オブジェクトが渡された
F_ERR_INVALID_PARAM 不正なパラメータが渡された
  • pnts または pnt_num がNULL
  • max_pnt_num が0以下
  • tlow > thigh
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー

INT FVALGAPI fnFIE_nms_dir ( FHANDLE  hmagx,
FHANDLE  hmagy,
FHANDLE  hthin,
DOUBLE  thresh 
)

非極大値の抑制(エッジ勾配方向を利用)

非極大抑制は、画像に対して1次微分を施した後に実行されます。 注目画素の勾配を、勾配方向に隣接した2つの画素の勾配と比較します。 注目画素の勾配が、隣接した画素の勾配より大きかった場合、局所的な最大値となり強度は保持されて、 後の処理に利用されます。 そうでない場合は、0が設定されます。

非極大抑制は、細線化のような効果があります。 しかしながら、勾配方向を考慮しており、処理結果は必ずしも1画素の幅の線になるとは限りません。

本関数では、出力画像の周囲1画素は0になります。 また、 hmagxhmagy で与えられたx方向とy方向の強度は、以下のように決定されます。

  • x、y方向共にエッジがない場合:0
  • x方向のみエッジがある場合:1
  • y方向のみエッジがある場合:2
  • x、y方向共にエッジがある場合:3
thresh は勾配の非常に小さい値を取り除くために利用されます。 hmagxhmagy は絶対値演算がなされた後、加算演算がなされます。 加算演算された画像に対して、 thresh 未満の値は0となります。 thresh は、0以上の値を入力してください。

hmagx , hmagy , hthin の幅、高さ共に3以上である必要があります。 また、すべての画像のサイズも同じである必要があります。

出力画像の周囲1画素は0となります。

以下に処理結果を示します。 fnFIE_sobel() により、x方向、y方向に処理した微分データを hmagxhmagy 、そして thresh を 64 として 処理しています。 なお hmagxhmagy は、入出力画像の画素タイプが共に F_IMG_UC8 として処理した場合を以下に示していますが、 実際の処理では出力画像の画素タイプは F_IMG_S16 として処理したデータを用いて、非極大値の抑制処理を行っています。 また細線化画像は、実際の値を85倍して表示しています。 (1)入力画像、(2)x方向微分データ画像、(3)y方向微分データ画像、(4)処理結果画像となります。

fie_nms_dir.png

引数:
[in] hmagx X方向のエッジ強度画像(type:s16, double)
[in] hmagy Y方向のエッジ強度画像(type:s16, double)
[out] hthin 細線化画像(type:uc8)
[in] thresh 非常に小さい勾配を取り除くための閾値
戻り値:
F_ERR_NONE 正常終了
F_ERR_INVALID_IMAGE 不正な画像が渡された
F_ERR_INVALID_PARAM 不正なパラメータが渡された
  • thresh が0未満
F_ERR_NOMEMORY メモリ不足
F_ERR_NO_LICENCE ライセンスエラー、または未初期化エラー
使用例
// エラー処理は省略しているので注意して下さい
#include "fie.h"
#include "oal_aloc.h"

INT main()
{
    FHANDLE hsrc = NULL;    // (1) 入力画像

    FHANDLE hmagx = NULL;   // (2) x方向微分データ画像
    FHANDLE hmagy = NULL;   // (3) y方向微分データ画像
    FHANDLE hthin = NULL;   // (4) 処理結果画像(細線化画像)

    DOUBLE thresh = 64.0;   // 非常に小さい勾配を取除く為の閾値

    // FIEライブラリの初期化処理
    fnFIE_setup();

    // 入力画像をファイルから読み込む
    fnFIE_load_png("src_img.png", &hsrc, F_COLOR_IMG_TYPE_UC8);

    // 画像オブジェクトの生成
    hmagx = fnFIE_img_root_alloc(F_IMG_S16, 1, fnFIE_img_get_width(hsrc), fnFIE_img_get_height(hsrc));
    hmagy = fnFIE_img_root_alloc(F_IMG_S16, 1, fnFIE_img_get_width(hsrc), fnFIE_img_get_height(hsrc));
    hthin = fnFIE_img_root_alloc(F_IMG_UC8, 1, fnFIE_img_get_width(hsrc), fnFIE_img_get_height(hsrc));

    // 入力画像をx方向で微分する
    fnFIE_sobel(hsrc, hmagx, F_SOBEL_X_MODE, F_BORDER_NONE, 0.0);

    // 入力画像をy方向で微分する
    fnFIE_sobel(hsrc, hmagy, F_SOBEL_Y_MODE, F_BORDER_NONE, 0.0);

    // 非極大値の抑制(エッジ勾配方向を利用)の実行
    fnFIE_nms_dir(hmagx, hmagy, hthin, thresh);

    // 可視化の為、細線化画像の濃度値を85倍にする
    fnFIE_img_mul_const(hthin, 85.0, hthin);

    // 細線化画像をファイルへ保存する
    fnFIE_save_png("dst_img.png", hthin, 9);

    // 画像オブジェクトの解放
    fnFIE_free_object(hsrc);
    fnFIE_free_object(hmagx);
    fnFIE_free_object(hmagy);
    fnFIE_free_object(hthin);

    // FIEライブラリの終了処理
    fnFIE_teardown();

    return 0;
}
参照:
fnFIE_nms()


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