ピーク探索

Namespace: fvalgcli
Assembly: fvalgcli (in fvalgcli.dll) Version: 3.1.0.0 (3.1.0.11)

Syntax

C#
public static int fnFIE_find_peaks(
	DOUBLE_PTR src_val,
	int src_num,
	int neighbor,
	int nms_length,
	int rel_length,
	double val_thresh,
	double rel_thresh,
	double max_abs_diff,
	int sort_mode,
	DOUBLE_PTR peaks_val,
	DOUBLE_PTR peaks_pos,
	ref int peaks_num
)
Visual Basic
Public Shared Function fnFIE_find_peaks ( 
	src_val As DOUBLE_PTR,
	src_num As Integer,
	neighbor As Integer,
	nms_length As Integer,
	rel_length As Integer,
	val_thresh As Double,
	rel_thresh As Double,
	max_abs_diff As Double,
	sort_mode As Integer,
	peaks_val As DOUBLE_PTR,
	peaks_pos As DOUBLE_PTR,
	ByRef peaks_num As Integer
) As Integer

Parameters

src_val
Type: fvalgcli..::..DOUBLE_PTR
入力配列
src_num
Type: System..::..Int32
入力配列の要素数 ( 1 ≦ src_num )
neighbor
Type: System..::..Int32
近傍範囲 ( 0 ≦ neighbor ) 極大のデータ点から 前後それぞれ neighbor 個までの範囲を近傍とし、補間に利用します。 0 が指定された場合、補間なしとなります。
nms_length
Type: System..::..Int32
非極大抑制のフィルタ片幅 ( 0 ≦ nms_length ) 極大のデータ点の前後 nms_length の範囲に複数のピークが出現したとき、 そのうちの最もピーク値の大きいものを採用し、他は無視します。 同値の場合は、先に出現したピークが優先されます。 nms_length = 0 のときには、制限なしとなります。
rel_length
Type: System..::..Int32
相対的ピーク高の計算片幅 ( 0 ≦ rel_length ) 極大のデータ点の前後 rel_length の範囲内で相対的ピーク高を計算します。 rel_length = 0 のときには、入力配列全体が計算範囲となります。
val_thresh
Type: System..::..Double
ピーク値の閾値 入力値が val_thresh 未満のピークは出力されません。 val_thresh ≦ ( 入力値の最低値 ) の場合、制限なしとなります。
rel_thresh
Type: System..::..Double
相対的ピーク高の閾値 ( 0 ≦ rel_thresh ) 相対的ピーク高が rel_thresh 未満のピークは出力されません。 rel_thresh = 0 の場合、制限なしとなります。
max_abs_diff
Type: System..::..Double
差分絶対値の上限 ( 0 ≦ max_abs_diff ) 極大のデータ点と前後の隣接しているデータ点との差がどちらも max_abs_diff より大きいときには、ごましおノイズ等によって出現したピークとみなして無視します。 max_abs_diff の値が小さいほど、ノイズを抑制しやすくピークが出現しにくい傾向があり、 max_abs_diff の値が大きいほど、ノイズを抑制しにくくピークが出現しやすい傾向があります。 入力値の最大値と最小値の差の1/4程度を推奨します。 特に制限しない場合は、0 を指定してください。
sort_mode
Type: System..::..Int32
peaks_val と peaks_pos のソートモード (0: 位置基準昇順、1: 位置基準降順、2: ピーク値基準昇順、3: ピーク値基準降順)
peaks_val
Type: fvalgcli..::..DOUBLE_PTR
取得ピーク値保存用のバッファ sort_mode で指定された順にピーク値を格納します。 peaks_num 個以上の配列を確保したうえで、その配列を渡してください。
peaks_pos
Type: fvalgcli..::..DOUBLE_PTR
取得ピーク位置保存用のバッファ sort_mode で指定された順にピーク位置を格納します。 つまり、peaks_val[idx] と peaks_pos[idx] は対応しています。 peaks_num 個以上の配列を確保したうえで、その配列を渡してください。
peaks_num
Type: System..::..Int32%
ピークの個数 入力のときには、ピークを最大で何個出力するか ( 1以上 ) を指定します。 出力のときには、以下の数値となります。 検出されたピークの個数が peaks_num 以内の場合 : 検出されたピークの個数 検出されたピークの個数が peaks_num を超えた場合 : 入力時の peaks_num このとき、ソートモードに従い、順に peaks_num 個のピークを出力します。

Return Value

Type: Int32
以下のエラーコードを返します。

エラーコード:
f_err内容
F_ERR_NONE正常終了
F_ERR_INVALID_PARAMパラメータ異常
F_ERR_NOMEMORYメモリ不足エラー
F_ERR_NO_LICENCEライセンスエラー

Examples

C# Copy imageCopy
using System;
using System.Collections.Generic;
using System.Text;
using fvalgcli;

namespace TC
{
    public partial class FIE
    {
        [FvPluginExecute]
        public void fnFIE_find_peaks()
        {
            Console.WriteLine("fnFIE_find_peaks");

            int status = (int)f_err.F_ERR_NONE;

            FHANDLE hsrc = FHANDLE.Zero;
            DOUBLE_PTR pprj = DOUBLE_PTR.Zero;

            DOUBLE_PTR peaks_val = DOUBLE_PTR.Zero;
            DOUBLE_PTR peaks_pos = DOUBLE_PTR.Zero;

            try
            {
                // 入力画像の読み込み.
                api.fnFIE_load_png(TestImageDir + "/testdata/projection_rockwall.png", ref hsrc, f_color_img_type.F_COLOR_IMG_TYPE_UC8);
                api.fnFIE_img_not(hsrc, hsrc);

                int width = api.fnFIE_img_get_width(hsrc);
                int height = api.fnFIE_img_get_height(hsrc);

                int prj_width = 5;
                int prj_len = 0;
                int length = 0;

                DSGMT_T line = new DSGMT_T();
                line.st.x = width / 2;
                line.st.y = 0;
                line.ed.x = width / 2;
                line.ed.y = height - 1;

                // 計測ラインの長さを計算.
                api.fnFIE_edge1d_calc_projection_line_length(line, ref length);
                prj_len = (int)(length + 0.5);
                pprj = DOUBLE_PTR.alloc(prj_len);

                // 投影実行.
                F_ARRAY_INDEX valid_reg = new F_ARRAY_INDEX();
                status = api.fnFIE_edge1d_projection_line(hsrc, line, prj_width, pprj, prj_len, ref valid_reg);
                Assert.IsTrue(status == (int)f_err.F_ERR_NONE, "fnFIE_edge1d_projection_line: エラーが発生しました。({0})", (f_err)status);

                // ピーク探索.
                int neighbor = 0;
                int nms_length = 50;
                int rel_length = 0;
                double val_thresh = 0;
                double rel_thresh = 0;
                double max_abs_diff = 96;
                int sort_mode = 0;

                int peaks_num = 20;
                peaks_val = DOUBLE_PTR.alloc(peaks_num);
                peaks_pos = DOUBLE_PTR.alloc(peaks_num);
                status = api.fnFIE_find_peaks(pprj, prj_len, neighbor, nms_length, rel_length,
                    val_thresh, rel_thresh, max_abs_diff, sort_mode,
                    peaks_val, peaks_pos, ref peaks_num);

                // 確認用.
                using (var hdraw_image = fnPRV_draw_peaks(hsrc, 0, pprj, prj_len, peaks_val, peaks_pos, peaks_num))
                {
                    api.fnFIE_save_png(ResultDir + "/fnFIE_find_peaks.png", hdraw_image, -1);
                }
            }
            finally
            {
                // オブジェクトの開放.
                hsrc.Dispose();
                pprj.Dispose();
                peaks_val.Dispose();
                peaks_pos.Dispose();
            }
        }

        /// <summary>
        /// 描画 (画像の各行の投影データと各ピークの描画)
        /// </summary>
        /// <param name="hsrc">元画像</param>
        /// <param name="y_offset">投影データの開始位置 (Y座標)</param>
        /// <param name="proj_addr">投影データ</param>
        /// <param name="proj_length">投影データの要素数</param>
        /// <param name="peaks_val">ピーク値の配列</param>
        /// <param name="peaks_pos">ピーク位置の配列</param>
        /// <param name="peaks_num"></param>
        /// <returns>
        ///        描画結果の画像。解放必要。
        /// </returns>
        private FHANDLE fnPRV_draw_peaks(FHANDLE hsrc, int y_offset, DOUBLE_PTR proj_addr, int proj_length, DOUBLE_PTR peaks_val, DOUBLE_PTR peaks_pos, int peaks_num)
        {
            FHANDLE hdst = FHANDLE.Zero;
            DOUBLE_PTR color = DOUBLE_PTR.Zero;
            DPNT_T_PTR points = DPNT_T_PTR.Zero;

            try
            {
                // 入力画像の情報取得.
                int width = api.fnFIE_img_get_width(hsrc);
                int height = api.fnFIE_img_get_height(hsrc);

                // 出力画像の生成.
                hdst = api.fnFIE_img_root_alloc((int)f_imgtype.F_IMG_UC8, 3, width, height);

                FHANDLE hdst0 = FHANDLE.Zero;
                FHANDLE hdst1 = FHANDLE.Zero;
                FHANDLE hdst2 = FHANDLE.Zero;
                try
                {
                    hdst0 = api.fnFIE_img_child_alloc_single_ch(hdst, 0, 0, 0, width, height);    // CH0
                    hdst1 = api.fnFIE_img_child_alloc_single_ch(hdst, 1, 0, 0, width, height);    // CH1
                    hdst2 = api.fnFIE_img_child_alloc_single_ch(hdst, 2, 0, 0, width, height);    // CH2
                    api.fnFIE_img_copy_ex(hsrc, hdst0, 1, 0, 0);
                    api.fnFIE_img_copy_ex(hsrc, hdst1, 1, 0, 0);
                    api.fnFIE_img_copy_ex(hsrc, hdst2, 1, 0, 0);
                }
                finally
                {
                    hdst0.Dispose();
                    hdst1.Dispose();
                    hdst2.Dispose();
                }

                // 描画色.
                color = DOUBLE_PTR.alloc(3);    // R,G,B

                // 描画.
                color[0] = 255;
                color[1] = 255;
                color[2] = 0;
                for (int i = 0; i < proj_length - 1; i++)
                {
                    DPNT_T st = DPNT_T.init(proj_addr[i + 0], y_offset + i);
                    DPNT_T ed = DPNT_T.init(proj_addr[i + 1], y_offset + i);
                    api.fnFIE_draw_line_seg(hdst, color, st, ed);
                }

                // 描画.
                color[0] = 255;
                color[1] = 0;
                color[2] = 0;
                for (int i = 0; i < peaks_num; i++)
                {
                    DPNT_T st = DPNT_T.init(0, y_offset + peaks_pos[i]);
                    DPNT_T ed = DPNT_T.init(width, y_offset + peaks_pos[i]);
                    api.fnFIE_draw_line_seg(hdst, color, st, ed);
                }
            }
            finally
            {
                // オブジェクトの開放.
                color.Dispose();
                points.Dispose();
            }

            return hdst;
        }
    }
}


Visual Basic Copy imageCopy
Imports System.Collections.Generic
Imports System.Text
Imports fvalgcli

Public Partial Class FIE
    <FvPluginExecute> _
    Public Sub fnFIE_find_peaks()
        Console.WriteLine("fnFIE_find_peaks")

        Dim status As Integer = CInt(f_err.F_ERR_NONE)

        Dim hsrc As FHANDLE = FHANDLE.Zero
        Dim pprj As DOUBLE_PTR = DOUBLE_PTR.Zero

        Dim peaks_val As DOUBLE_PTR = DOUBLE_PTR.Zero
        Dim peaks_pos As DOUBLE_PTR = DOUBLE_PTR.Zero

        Try
            ' 入力画像の読み込み.
            api.fnFIE_load_png(TestImageDir & "/testdata/projection_rockwall.png", hsrc, f_color_img_type.F_COLOR_IMG_TYPE_UC8)
            api.fnFIE_img_not(hsrc, hsrc)

            Dim width As Integer = api.fnFIE_img_get_width(hsrc)
            Dim height As Integer = api.fnFIE_img_get_height(hsrc)

            Dim prj_width As Integer = 5
            Dim prj_len As Integer = 0
            Dim length As Integer = 0

            Dim line As New DSGMT_T()
            line.st.x = width \ 2
            line.st.y = 0
            line.ed.x = width \ 2
            line.ed.y = height - 1

            ' 計測ラインの長さを計算.
            api.fnFIE_edge1d_calc_projection_line_length(line, length)
            prj_len = CInt(Math.Truncate(length + 0.5))
            pprj = DOUBLE_PTR.alloc(prj_len)

            ' 投影実行.
            Dim valid_reg As New F_ARRAY_INDEX()
            status = api.fnFIE_edge1d_projection_line(hsrc, line, prj_width, pprj, prj_len, valid_reg)
            Assert.IsTrue(status = CInt(f_err.F_ERR_NONE), "fnFIE_edge1d_projection_line: エラーが発生しました。({0})", CType(status, f_err))

            ' ピーク探索.
            Dim neighbor As Integer = 0
            Dim nms_length As Integer = 50
            Dim rel_length As Integer = 0
            Dim val_thresh As Double = 0
            Dim rel_thresh As Double = 0
            Dim max_abs_diff As Double = 96
            Dim sort_mode As Integer = 0

            Dim peaks_num As Integer = 20
            peaks_val = DOUBLE_PTR.alloc(peaks_num)
            peaks_pos = DOUBLE_PTR.alloc(peaks_num)
            status = api.fnFIE_find_peaks(pprj, prj_len, neighbor, nms_length, rel_length, val_thresh, _
                rel_thresh, max_abs_diff, sort_mode, peaks_val, peaks_pos, peaks_num)

            ' 確認用.
            Using hdraw_image As FHANDLE = fnPRV_draw_peaks(hsrc, 0, pprj, prj_len, peaks_val, peaks_pos, _
                peaks_num)
                api.fnFIE_save_png(ResultDir & "/fnFIE_find_peaks.png", hdraw_image, -1)
            End Using
        Finally
            ' オブジェクトの開放.
            hsrc.Dispose()
            pprj.Dispose()
            peaks_val.Dispose()
            peaks_pos.Dispose()
        End Try
    End Sub

    ''' <summary>
    ''' 描画 (画像の各行の投影データと各ピークの描画)
    ''' </summary>
    ''' <param name="hsrc">元画像</param>
    ''' <param name="y_offset">投影データの開始位置 (Y座標)</param>
    ''' <param name="proj_addr">投影データ</param>
    ''' <param name="proj_length">投影データの要素数</param>
    ''' <param name="peaks_val">ピーク値の配列</param>
    ''' <param name="peaks_pos">ピーク位置の配列</param>
    ''' <param name="peaks_num"></param>
    ''' <returns>
    '''        描画結果の画像。解放必要。
    ''' </returns>
    Private Function fnPRV_draw_peaks(hsrc As FHANDLE, y_offset As Integer, proj_addr As DOUBLE_PTR, proj_length As Integer, peaks_val As DOUBLE_PTR, peaks_pos As DOUBLE_PTR, _
        peaks_num As Integer) As FHANDLE
        Dim hdst As FHANDLE = FHANDLE.Zero
        Dim color As DOUBLE_PTR = DOUBLE_PTR.Zero
        Dim points As DPNT_T_PTR = DPNT_T_PTR.Zero

        Try
            ' 入力画像の情報取得.
            Dim width As Integer = api.fnFIE_img_get_width(hsrc)
            Dim height As Integer = api.fnFIE_img_get_height(hsrc)

            ' 出力画像の生成.
            hdst = api.fnFIE_img_root_alloc(CInt(f_imgtype.F_IMG_UC8), 3, width, height)

            Dim hdst0 As FHANDLE = FHANDLE.Zero
            Dim hdst1 As FHANDLE = FHANDLE.Zero
            Dim hdst2 As FHANDLE = FHANDLE.Zero
            Try
                hdst0 = api.fnFIE_img_child_alloc_single_ch(hdst, 0, 0, 0, width, height)
                ' CH0
                hdst1 = api.fnFIE_img_child_alloc_single_ch(hdst, 1, 0, 0, width, height)
                ' CH1
                hdst2 = api.fnFIE_img_child_alloc_single_ch(hdst, 2, 0, 0, width, height)
                ' CH2
                api.fnFIE_img_copy_ex(hsrc, hdst0, 1, 0, 0)
                api.fnFIE_img_copy_ex(hsrc, hdst1, 1, 0, 0)
                api.fnFIE_img_copy_ex(hsrc, hdst2, 1, 0, 0)
            Finally
                hdst0.Dispose()
                hdst1.Dispose()
                hdst2.Dispose()
            End Try

            ' 描画色.
            color = DOUBLE_PTR.alloc(3)
            ' R,G,B
            ' 描画.
            color(0) = 255
            color(1) = 255
            color(2) = 0
            For i As Integer = 0 To proj_length - 2
                Dim st As DPNT_T = DPNT_T.init(proj_addr(i + 0), y_offset + i)
                Dim ed As DPNT_T = DPNT_T.init(proj_addr(i + 1), y_offset + i)
                api.fnFIE_draw_line_seg(hdst, color, st, ed)
            Next

            ' 描画.
            color(0) = 255
            color(1) = 0
            color(2) = 0
            For i As Integer = 0 To peaks_num - 1
                Dim st As DPNT_T = DPNT_T.init(0, y_offset + peaks_pos(i))
                Dim ed As DPNT_T = DPNT_T.init(width, y_offset + peaks_pos(i))
                api.fnFIE_draw_line_seg(hdst, color, st, ed)
            Next
        Finally
            ' オブジェクトの開放.
            color.Dispose()
            points.Dispose()
        End Try

        Return hdst
    End Function
End Class

See Also