道格拉斯-普克 Douglas-Peuker(DP算法) python java实现

【Python】道格拉斯-普克抽稀算法 常用的地图点压缩 from math import sqrt, pow def point_to_line_Distance(point_a, point_b, point_c): """ 计算点a到点b c所在直线的距离 :param point_a: :param point_b: :param point_c: :return: """ # 首先计算b c 所在直线的斜率和截距 if point_b[0] == point_c 阅读详情

1、道格拉斯-普克抽稀算法说明

道格拉斯-普克抽稀算法是用来对大量冗余的图形数据点进行压缩以提取必要的数据点。
该算法实现抽稀的过程是:
1)对曲线的首末点虚连一条直线,求曲线上所有点与直线的距离,并找出最大距离值dmax,用dmax与事先给定的阈值D相比: 
2)若dmax<D,则将这条曲线上的中间点全部舍去;则该直线段作为曲线的近似,该段曲线处理完毕。 
  若dmax≥D,保留dmax对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法,即重复1),2)步,直到所有dmax均<D,即完成对曲线的抽稀。 
显然,本算法的抽稀精度也与阈值相关,阈值越大,简化程度越大,点减少的越多,反之,化简程度越低,点保留的越多,形状也越趋于原曲线。 

2、举例说明

输出结果:1.0 4.0,4.0 2.0,7.0 7.0,9.0 5.0,10.0 10.0,其中2 3,6 6,8 6两个坐标被抽稀掉了。

示意图:

假设在平面坐标系上有一条由N个坐标点组成的曲线,已设定一个阈值epsilon。
(1)首先,将起始点与结束点用直线连接, 再找出到该直线的距离最大,同时又大于阈值epsilon的点并记录下该点的位置(这里暂且称其为最大阈值点),如图所示:

(2)接着,以该点为分界点,将整条曲线分割成两段(这里暂且称之为左曲线和右曲线),将这两段曲线想象成独立的曲线然后重复操作(1),找出两边的最大阈值点,如图所示:

(3)最后,重复操作(2)(1)直至再也找不到最大阈值点为止,然后将所有最大阈值点按顺序连接起来便可以得到一条更简化的,更平滑的,与原曲线十分近似的曲线,如图所示:


3、Java代码实现

Point类:

public class Point {
    double x;
    double y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
        System.out.print("(" + x + "," + y + ") ");
    }

    public static Point instance(int x, int y) {
        return new Point(x, y);
    }
}

DouglasPeuckerUtil 类:

public class DouglasPeuckerUtil {

    public static void main(String[] args) {

        System.out.print("原始坐标:");

        List<Point> points = new ArrayList<>();
        List<Point> result = new ArrayList<>();

        points.add(Point.instance(1, 1));
        points.add(Point.instance(2, 2));
        points.add(Point.instance(3, 4));
        points.add(Point.instance(4, 1));
        points.add(Point.instance(5, 0));
        points.add(Point.instance(6, 3));
        points.add(Point.instance(7, 5));
        points.add(Point.instance(8, 2));
        points.add(Point.instance(9, 1));
        points.add(Point.instance(10, 6));

        System.out.println("");
        System.out
                .println("=====================================================================");
        System.out.print("抽稀坐标:");

        result = DouglasPeucker(points, 1);

        for (Point p : result) {
            System.out.print("(" + p.x + "," + p.y + ") ");
        }
    }

    public static List<Point> DouglasPeucker(List<Point> points, int epsilon) {
        // 找到最大阈值点,即操作(1)
        double maxH = 0;
        int index = 0;
        int end = points.size();
        for (int i = 1; i < end - 1; i++) {
            double h = H(points.get(i), points.get(0), points.get(end - 1));
            if (h > maxH) {
                maxH = h;
                index = i;
            }
        }

        // 如果存在最大阈值点,就进行递归遍历出所有最大阈值点
        List<Point> result = new ArrayList<>();
        if (maxH > epsilon) {
            List<Point> leftPoints = new ArrayList<>();// 左曲线
            List<Point> rightPoints = new ArrayList<>();// 右曲线
            // 分别提取出左曲线和右曲线的坐标点
            for (int i = 0; i < end; i++) {
                if (i <= index) {
                    leftPoints.add(points.get(i));
                    if (i == index)
                        rightPoints.add(points.get(i));
                } else {
                    rightPoints.add(points.get(i));
                }
            }

            // 分别保存两边遍历的结果
            List<Point> leftResult = new ArrayList<>();
            List<Point> rightResult = new ArrayList<>();
            leftResult = DouglasPeucker(leftPoints, epsilon);
            rightResult = DouglasPeucker(rightPoints, epsilon);

            // 将两边的结果整合
            rightResult.remove(0);//移除重复点
            leftResult.addAll(rightResult);
            result = leftResult;
        } else {// 如果不存在最大阈值点则返回当前遍历的子曲线的起始点
            result.add(points.get(0));
            result.add(points.get(end - 1));
        }
        return result;
    }

    /**
     * 计算点到直线的距离
     * 
     * @param p
     * @param s
     * @param e
     * @return
     */
    public static double H(Point p, Point s, Point e) {
        double AB = distance(s, e);
        double CB = distance(p, s);
        double CA = distance(p, e);

        double S = helen(CB, CA, AB);
        double H = 2 * S / AB;

        return H;
    }

    /**
     * 计算两点之间的距离
     * 
     * @param p1
     * @param p2
     * @return
     */
    public static double distance(Point p1, Point p2) {
        double x1 = p1.x;
        double y1 = p1.y;

        double x2 = p2.x;
        double y2 = p2.y;

        double xy = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        return xy;
    }

    /**
     * 海伦公式,已知三边求三角形面积
     * 
     * @param cB
     * @param cA
     * @param aB
     * @return 面积
     */
    public static double helen(double CB, double CA, double AB) {
        double p = (CB + CA + AB) / 2;
        double S = Math.sqrt(p * (p - CB) * (p - CA) * (p - AB));
        return S;
    }

输出结果:

 

4 Python代码实现

4.1 递归实现

4.2 非递归实现

参考:

1、https://www.jianshu.com/p/bf595477a124

2、https://zhuanlan.zhihu.com/p/74906781

3、https://blog.youkuaiyun.com/cdl2008sky/article/details/7701769

 

 

 

矢量数据压缩算法“Douglas-Peucker”——递归与非递归实现(python) 思路参考w https://blog.youkuaiyun.com/johntzh/article/details/114916069#comments_16881210 阅读详情

相关推荐

Python实现关键点提取之Douglas–Peucker算法

Douglas–Peucker算法的核心思想是递归地删除曲线上那些不影响整体形状的点。它通过找出一条折线的关键点,将这些点连接成简化的曲线,而其它非关键点则被移除。给定一条曲线,由一系列有序的点集组成。取曲线的第一个点和最后一个点作为简化曲线的初始关键点。寻找曲线上离当前简化曲线最远的点,如果该点到简化曲线的距离大于给定的阈值,则将其加入简化曲线的关键点集合中。递归地对该点之前和之后的子曲线重复步骤2和3,直到没有点需要加入为止。最终结果是一条由较少点构成的简化曲线。

闲人编程的博客 2321

曲线点抽稀算法-Python实现

何为抽稀 在处理矢量化数据时,记录中往往会有很多重复数据,对进一步数据处理带来诸多不便。多余的数据一方面浪费了较多的存储空间,另一方面造成所要表达的图形不光滑或不符合标准。因此要通过某种规则,在保证矢量曲线形状不变的情况下, 最大限度地减少数据点个数,这个过程称为抽稀。 通俗的讲就是对曲线...

chenxuan5849的博客 1440

Python关键点提取之Douglas–Peucker算法

Douglas-Peucker算法的主要目标是:在保持多边形形状特征的同时,通过去除一些冗余点来减少点的数量。这对处理大量坐标点的应用场景非常有帮助,比如在地图、路径简化中降低数据量,提高处理速度。本文通过面向对象的方式详细实现了Douglas-Peucker算法,并结合具体的代码示例展示了如何简化点集。Douglas-Peucker算法在各种需要简化点集、压缩数据的应用场景中非常有用,尤其是GPS轨迹简化、地图边界简化等领域。

闲人编程的博客 1606

Douglas–Peucker算法python实现

递归方式实现的Douglas–Peucker算法用于GPS轨迹压缩,参考的原文找不到了,把它封装成一个类。 import math class Point(object): def __init__(self, id, x, y): self.id = id self.x = x self.y = y class DPCompress(object): def __init__(self, pointList, tolerance):

rover 2493

曲线点抽稀算法的Python实现

本文介绍了曲线点抽稀算法的原理,并提供了使用Python实现该算法的源代码。通过使用该算法,我们可以有效地减少曲线数据的点数量,从而减小数据集的大小,同时保持关键形状特征。曲线点抽稀算法的基本原理是通过移除曲线上距离较近的点,以达到减少数据量的目的。具体而言,算法通过计算曲线上相邻点之间的距离,并与给定的阈值进行比较。曲线点抽稀算法是一种用于减少曲线上冗余点的技术,以保持关键形状特征的同时减少数据量。该函数通过遍历曲线上的点,并与上一个点进行距离比较,根据阈值判断是否保留该点。,其中包含了一系列点的坐标。

CyberJolt的博客 242

道格拉斯-普克抽稀算法,java 实现

道格拉斯-普克抽稀算法,java 实现

道格拉斯算法 java_道格拉斯-普克 Douglas-Peuker(DP算法) python java实现

1、道格拉斯-普克抽稀算法说明道格拉斯-普克抽稀算法是用来对大量冗余的图形数据点进行压缩以提取必要的数据点。该算法实现抽稀的过程是:1)对曲线的首末点虚连一条直线,求曲线上所有点与直线的距离,并找出最大距离值dmax,用dmax与事先给定的阈值D相比:2)若dmax若dmax≥D,保留dmax对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法,即重复1),2)步,直到所有dma...

weixin_31099497的博客 881

Douglas-Peucker算法 算法的Java实现

Douglas-Peucker算法 在数字化过程中,需要对曲线进行采样简化,即在曲线上取有限个点,将其变为折线,并且能够在一定程度 上保持原有的形状。 经典的Douglas-Peucker算法描述如下: (1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦; (2)得到曲线上离该直线段距离最大的点C,计算其与AB的距离d; (3)比较该距离与预先给定的阈值threshold的大小,如果小于threshold,则该直线段作为曲线的近似,该段曲线处理完毕。 (4)如果距离大于阈值,则用C将曲线分为两段AC和BC,并分别对两段取信进行1~3的处理。 (5)当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似。

曲线抽稀 java_Python实现曲线点抽稀算法

目录何为抽稀道格拉斯-普克(Douglas-Peuker)算法垂距限值法最后正文何为抽稀在处理矢量化数据时,记录中往往会有很多重复数据,对进一步数据处理带来诸多不便。多余的数据一方面浪费了较多的存储空间,另一方面造成所要表达的图形不光滑或不符合标准。因此要通过某种规则,在保证矢量曲线形状不变的情况下, 最大限度地减少数据点个数,这个过程称为抽稀。通俗的讲就是对曲线进行采样简化,即在曲线上取有限个点...

weixin_39688170的博客 436

Douglas-Peucker 算法:Douglas-Peucker 算法减少曲线中的点数。-matlab开发

% Ramer-Douglas-Peucker 算法 (RDP) 是一种减少% 曲线中由一系列近似的点数% 点。 该算法的初始形式是独立提出的% 于 1972 年由 Urs Ramer 和 1973 年由 David Douglas 和 Thomas Peucker 以及% 在接下来的十年中还有其他几个。 这个算法也是众所周知的% 以 Douglas-Peucker 算法命名,迭代终点拟合% 算法和拆分合并算法。 [来源维基百科] % % 输入: % 点数:点数列表 2xN % epsilon:距离维度,指定之间的相似度% 原始曲线和近似值(较小的 epsilon, % 曲线更相似) % 输出: % 结果:近似曲线 2xM (M<=N) 的点列表%

点集压缩算法douglas-peucker等

点集压缩算法,douglas-peucker,Radial distance,Nth point等。使用win7,VS2013,Qt5.5.1,64位编译。对原程序作了Qt适应性修改。psimpl_v7_win32_demo\src\demo\x64\Debug下的程序可直接运行,裸机已实验

Douglas-Peucker折线抽稀算法 Python 通过距离阈值控制和通过节点数量控制两种实现

折线抽稀 当折线点的数量过多时,往往需要对折线简化,且简化的折线能最大程度的保留原始折线的几何特征,这就是折线抽稀。主要的抽稀算法有Ramer-Douglas-Peucker、Visvalingam-Whyatt等,本文介绍Ramer-Douglas-Peucker算法。 Douglas-Peucker原理 具体原理可以参考Wiki或者其他博客,在此不过多介绍简单来说,Douglas-Peucker算法首先连接首尾两端,然后寻找折线上距离该线最远的点并计算距离,当距离大于距离阈值时,则保留改点,然后对首点

zzzzhhhhyyyy1的博客 3902

ICCompiler II实战:从NDM生成到APR流程的完整避坑指南

本文是一份针对ICCompiler II(ICC II)后端物理实现流程的实战避坑指南。文章详细解析了从NDM库生成、设计初始化、布局规划到时钟树综合与布线的完整APR流程,重点分享了各环节的常见陷阱、精细化配置命令与调试经验,旨在帮助工程师高效达成PPA目标,确保设计一次成功。

p4q5r6s7t的博客 531

道格拉斯普克(Douglas-Peuker)算法python实现

目录 前言 一、算法实现 二、输出结果 前言 本程序主要应用于边界线上点的稀释,本文提供随机数和交互式输入两种方式实现数据载入。 一、算法实现 # -*- coding = utf-8 -*- # @time:2021/6/5 21:39 # Author:scw # @File:DP.py # @Software:PyCharm # Environment:Python3.6 from math import sqrt import numpy as np import random as

Chandni_小月月 2760

双臂复合机器人眼在手外标定实战:从原理到D435标定流程详解

本文详细解析了双臂复合机器人中眼在手外标定的核心原理与实战流程。通过阐述坐标系转换与AX=XB方程,重点介绍了使用Intel RealSense D435相机进行标定的完整步骤,包括环境搭建、数据采集、计算与验证,并提供了关键的避坑指南,帮助工程师实现相机与机械臂基座间的精确坐标对齐。

weixin_29100927的博客 445

学习 考证 帆软 FCP-FineBI V6.0 考试经验

参加这个学习班,认识了新朋友,可能是我职业生涯中的一次重要体验,其实大家想想 IT 和 医生一样都是需要终身学习的。只是医生学习周期更长但是回报率也更高。大家觉的呢?

小 tom的博客 6223

【GIS算法】——道格拉斯-普克(Douglas-Peucker)Python实现及改进

拉默-道格拉斯-普克算法(Ramer–Douglas–Peucker algorithm),又称道格拉斯-普克算法(Douglas–Peucker algorithm)和迭代端点拟合算法(iterative end-point fit algorithm),是一种将线段组成的曲线降采样为点数较少的类似曲线的算法。它是最早成功地用于制图综合的算法之一。粒子群优化算法(Particle Swarm Optimization,PSO)是进化计算的一个分支,是一种模拟自然界的生物活动的随机搜索算法。

weixin_75138529的博客 1904

HDRP shader 获取阴影(Custom Pass)

Unity:2021.3.0f1 HDRP:12.1.6

LanQ的博客 2097

Douglas-Peucker算法+Gaussian模糊 OpenCV(2.4.9)-Python实现

import cv2 as cv #import numpy as np def Gaussian(image): image1=cv.GaussianBlur(image,(11,11),0) image2=image-image1 return image2 def main(): #img=cv.imread("star.jpg",0) #...

AliceWhale 672

智能优化电池:基于单片机的电池管理系统

设计简介: 本设计是基于单片机的电池管理系统,主要实现以下功能: 可通过LCD1602显示温度、电压电流值; 可通过按键调整温度、电压和电流的阈值; 用ADC0832将模拟量转换为数字量。 标签:51单片机、LCD1602、ADC0832 效果图: 总体资料: 原理图: 软件设计流程: 系统框图: 本设计以STC89C52单片机为核心控制器,加上其他的模块一起组成电动汽车的电池管理的整个系统,...

专注单片机实战教学,分享单片机学习资料 375

quartus 13.1常见报错解决方法

在使用quartus中会遇到很多由于安装或设置不规范造成的错误。我就目前我遇到的一些错误以及我的解决方法分享给大家,这个文章将会持续更新,如果读者有遇到软件中错误无法解决的问题,也欢迎在评论区留言。 一、编译出现lience错误 在对设计的电路编译时,系统在程序运行3秒内即结束并报错,大概意思为现有的证书不支持编译。这个常见问题源自破解不成功,这里读者很有可能犯的错误是在使用破解器的时候没有区分x86(即32-bit)和x64软件破解器对应的文件夹。 如图所示有两种破解器,分别对应32位和64位的软件,大部

肥宅的博客 3万+

道格拉斯-普客抽稀算法及测试(python动态图解)

道格拉斯-普客抽稀算法的动态图解

累了就要打游戏 1829

【HAL库-STM】智能温控按键小风扇【胎教级教学】

硬件设备:DHT11,0.96寸oled屏,二/三/四线风扇(不挑),面包板 、f10的精英板等等。当人在的风扇面前时可以自行控制风扇,不在面前时又想开风扇就让他温控自行开启,(在这里有一个想法就是加上蓝牙和wifi控制的功能能够远程遥控,这个如果做的再全一点就要自主研发是一个多功能app,这里没有做。针对这个dht11,我一开始是卡在了这个check函数里面,一直是我给完dht11低电平和高电平后,dht11不回复我低电平和高电平,这个不是我的问题,当时代码是没毛病的,这个点一直卡着我。吐血五天实现小成品

weixin_52451652的博客 1737

Python实现:Douglas-Peucker算法实现压缩geojson多边形数据

这段代码的主要功能是:1. Douglas-Peucker 算法用于对多边形的点集进行压缩。2. 在给定目录中遍历所有 `.json` 文件,对指定标签的形状数据进行压缩。3. 输出压缩后的数据并覆盖原有文件。本文展示了如何使用 Douglas-Peucker 算法对 JSON 文件中的多边形点集进行压缩。在实际应用中,适当调整 `epsilon` 和 `target_points` 参数,可以在压缩率和数据精度之间找到平衡。

C747217368的博客 663

IGBT基础知识及应用电路仿真(Multisim)

本文系统介绍了IGBT(绝缘栅双极晶体管)及其应用电路。首先详细解析了IGBT的基本结构、工作原理和特性参数,重点阐述了其五层半导体结构、电导调制效应和电压驱动特性。随后通过Multisim仿真展示了IGBT在四种典型功率变换电路中的应用:半桥驱动电路实现隔离式互补驱动;全桥逆变电路完成DC-AC转换;三相桥式逆变电路生成三相交流电;直流斩波电路(BUCK/BOOST/BUCK-BOOST)实现电压升降变换。文章通过理论分析与仿真波形相结合,全面呈现了IGBT在中高压大功率场景下的优异性能和灵活应用。

XU157303764的博客 1216

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Java【算法 01】道格拉斯-普克 Douglas-Peucker 抽稀算法(算法流程图解+使用JDK8方法实现+详细注解源码)

Java【算法 01】道格拉斯-普克 Douglas-Peucker 抽稀算法(算法流程图解+使用JDK8方法实现+详细注解源码)

Java与大数据相关实践内容分享! 5491

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

上一篇: pycharm 自动生成文件注释和函数注释
下一篇: Python2和Python3除法差别
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值