波峰波谷(凸点凹点)的检测算法

波峰波谷(凸点凹点)的检测算法

主要使用算子:


前言

在Halcon轮廓线处理中,我们可能需要找到轮廓线的转折点位置进行处理(在这里我们称它为波峰波谷),如下图(绿色的是凹点、蓝色的是凸点):
图1

我们算法要实现的就是上述效果,主要参考信号波峰波谷二阶差分识别算法,对原理感兴趣的可以去看这篇文章。不多说,直接上代码。


前期准备

halcon任一版本(我使用19.11)。

代码

main函数代码:

dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
Rows := [150,150,50,150,140,180,200,150]
Cols := [0,50,200,300,400,450,500,600]
gen_cross_contour_xld (Cross, Rows, Cols, 12, 0.785398)
gen_nurbs_interp (Rows, Cols, [0,-10,0,10], 3, CtrlRows, CtrlCols, Knots)
gen_contour_nurbs_xld (Contour, CtrlRows, CtrlCols, Knots, 'auto', 3, 1, 5)
dev_display (Contour)
dev_display (Cross)

get_contour_xld(Contour, RowS,ColumnS)

FindPV_COPY_1 (RowS, Pos_PeakL, Pos_ValleyL, Pos_Peak, Pos_Valley)

*波峰显示
for j := 0 to  Pos_PeakL-1 by 1
    
    Pos_PeakY[j]:=RowS[Pos_Peak[j]]
    Pos_PeakX[j]:=ColumnS[Pos_Peak[j]]
      
endfor

*波谷显示
for j := 0 to  Pos_ValleyL-1 by 1
    
    Pos_ValleyY[j]:=RowS[Pos_Valley[j]]
    Pos_ValleyX[j]:=ColumnS[Pos_Valley[j]]
      
endfor

gen_cross_contour_xld (Pos_PeakCross, Pos_PeakY, Pos_PeakX, 100, 0.785398)
gen_cross_contour_xld (Pos_ValleyCross, Pos_ValleyY, Pos_ValleyX, 100, 0.785398)
dev_clear_window()
dev_set_color('red')
dev_display(Contour)


dev_set_color('green')
dev_display(Pos_PeakCross)
dev_set_color('blue')

dev_display(Pos_ValleyCross)

函数 FindPV_COPY_1 代码与输入输出:

FindPV_COPY_1

* 初始化相关数据
tuple_length (PointValue, SAMPLE_MAX)

* Pos_Peak   //波峰位置存储
* Pos_Valley //波谷位置存储



SampleDiff := gen_tuple_const(|PointValue|,0)

* step 1 :首先进行前向差分,并归一化
for i := 0 to SAMPLE_MAX-2 by 1

    d := PointValue[i+1]-PointValue[i]
    if (d>0)
        SampleDiff[i] := 1
    elseif (d<0)
        SampleDiff[i] := -1
    else
        SampleDiff[i] := 0
    endif

endfor

* step 2 :对相邻相等的点进行领边坡度处理
for i := 0 to SAMPLE_MAX-2 by 1
    if (SampleDiff[i]==0)

        if (i==(SAMPLE_MAX-2))

            if (SampleDiff[i - 1] >= 0)
                SampleDiff[i] := 1
            else
                SampleDiff[i] := -1
            endif
        else
            if (SampleDiff[i + 1] >= 0)
                SampleDiff[i] := 1
            else
                SampleDiff[i] := -1
            endif
        endif
    endif
endfor

* step 3 :对相邻相等的点进行领边坡度处理
Pos_PeakL := 0
Pos_ValleyL := 0
for i := 0 to SAMPLE_MAX - 2 by 1
    * //波峰识别
    if (SampleDiff[i + 1] - SampleDiff[i] == -2)
        Pos_Peak[Pos_PeakL] := i+1
        Pos_PeakL := Pos_PeakL+1
        * //波谷识别
    elseif (SampleDiff[i + 1] - SampleDiff[i] == 2)
        Pos_Valley[Pos_ValleyL] := i+1
        Pos_ValleyL := Pos_ValleyL+1
    endif

endfor
return ()

总结

下次分享C#版拟合直线代码。