1、介绍
道格拉斯-普克算法由David H. Douglas和Thomas K. Peucker于1973年提出,主要用于简化曲线或折线。而实际中,激光点云的边缘点非常粗糙,如果直接将点进行连接,锯齿问题严重。经过DP算法处理后,数据显示会比较光滑,符合认知。
2、原理介绍
对每一条曲线的首末点虚连一条直线,求所有点与直线的距离,并找出最大距离值dmax,用dmax与限差D相比。若dmax<D,这条曲线上的中间点全部舍去;若dmax ≥D,保留dmax对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法。
算法的详细步骤如下:
(1) 在曲线首尾两点间虚连一条直线,求出其余各点到该直线的距离,如图(1)。
(2) 选其最大者与阈值相比较,若大于阈值,则离该直线距离最大的点保留,否则将直线两端点间各点全部舍去,如图(2),第4点保留。
(3) 依据所保留的点,将已知曲线分成两部分处理,重复第1、2步操作,迭代操作,即仍选距离最大者与阈值比较,依次取舍,直到无点可舍去,最后得到满足给定精度限差的曲线点坐标,如图(3)、 (4)依次保留第6点、第7点,舍去其他点,即完成线的化简。
3、算法测试
3.1 源代码与测试数据说明
使用python语言,在pycharm平台上按照上述原理对其实现,源代码下载链接:https://download.csdn.net/download/qq_32867925/90283351
包括源代码与三块测试数据。
3.2 使用说明
首先说明的是,提取的边缘点必须要有序结构,即将点依次连接起来,是一个闭合的结构,如下图所示。对于无序轮廓点,本程序不适合。若建构简单点云,可参考之前博客点云轮廓点排序——旋转角法(python pycharm)_不规则点云排序-CSDN博客,对轮廓点进行排序。
使用时,需要修改( filepath = "D:\\长方形.txt")这一块路径,修改成自己电脑上存储路径即可。
# 生成示例点云数据
def generate_example_points():boundpts = []filepath = "D:\\长方形.txt"with open(filepath, 'r') as pointsFile:for line in pointsFile:x, y, z, r, g, b = map(float, line.split())if r == 255 and g == 0 and b == 0:boundpts.append([x, y])boundpts = np.array(boundpts)return boundpts
这一块为随机生成的100个数据,使用DP算法对其进行精简。
# 生成示例点云数据
def generate_example_points():"""生成一个示例点云"""x = np.linspace(0, 10, 100)y = np.sin(x) + np.random.normal(0, 0.1, size=len(x)) # 添加噪声return np.column_stack((x, y))
3.3 测试一:随机数精简
如下是随机生成100个数据,使用DP算法精简结果。使用不同距离阈值约束,精简效果不相同。其中绿色多边形为精简后的直线,红色点为关键点。
3.4 测试二:多边形精简
多边形点进行精简,精简效果理想。其中绿色多边形为精简后的直线,红色点为关键点。
3.5 测试三:规则矩形
对于规则矩形,精简后为矩形,效果理想。其中绿色多边形为精简后的直线,红色点为关键点。