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

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

主要使用算子:


前言

在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#版拟合直线代码。

  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
迷宫中的转折点可以定义为路径中一个方向改变的点,即从直走变为拐弯或从拐弯变为直走的点。以下是一个简单的C语言代码示例,可以输出迷宫中所有的转折点坐标: ```c #include <stdio.h> #define ROW 10 #define COL 10 int maze[ROW][COL] = { // 迷宫地图,0表示可走,1表示障碍物 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 0, 1, 1, 0, 1, 1, 0}, {0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 0, 1, 1, 1, 1}, {0, 1, 0, 0, 1, 0, 0, 0, 0, 1}, {0, 1, 0, 1, 1, 0, 1, 1, 0, 1}, {0, 1, 0, 0, 0, 0, 0, 1, 0, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 0, 0} }; int visited[ROW][COL] = {0}; // 标记数组,记录是否访问过 void find_turning_points(int x, int y, int dir) { visited[x][y] = 1; // 标记当前位置已经访问过 if (dir == 1 && x > 0 && maze[x-1][y] == 0 && (y == 0 || maze[x][y-1] == 1)) { printf("(%d, %d)\n", x, y); // 打印转折点坐标 } if (dir == 2 && y < COL-1 && maze[x][y+1] == 0 && (x == 0 || maze[x-1][y] == 1)) { printf("(%d, %d)\n", x, y); } if (dir == 3 && x < ROW-1 && maze[x+1][y] == 0 && (y == COL-1 || maze[x][y+1] == 1)) { printf("(%d, %d)\n", x, y); } if (dir == 4 && y > 0 && maze[x][y-1] == 0 && (x == ROW-1 || maze[x+1][y] == 1)) { printf("(%d, %d)\n", x, y); } if (x > 0 && maze[x-1][y] == 0 && !visited[x-1][y]) { find_turning_points(x-1, y, 1); // 向上走 } if (y < COL-1 && maze[x][y+1] == 0 && !visited[x][y+1]) { find_turning_points(x, y+1, 2); // 向右走 } if (x < ROW-1 && maze[x+1][y] == 0 && !visited[x+1][y]) { find_turning_points(x+1, y, 3); // 向下走 } if (y > 0 && maze[x][y-1] == 0 && !visited[x][y-1]) { find_turning_points(x, y-1, 4); // 向左走 } } int main() { find_turning_points(0, 0, 2); // 从起点开始,初始方向向右 return 0; } ``` 在这个代码中,我们使用了递归的方式遍历迷宫,找到所有的转折点。对于每个未访问过的位置,我们分别向四个方向进行探索,如果当前方向上的下一个位置可以走,并且之前没有访问过,则继续递归搜索。当我们到达一个转折点时,根据当前的方向和周围的障碍物情况,判断是否是一个转折点,并输出其坐标。注意,我们需要使用一个 `visited` 数组来记录哪些位置已经访问过,防止重复访问。 在这个代码中,我们假设起点在左上角,初始方向向右。如果你的起点和方向不同,可以相应地修改输入参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值