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.csdn.net/cdl2008sky/article/details/7701769

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

  1. 道格拉斯—普克(Douglas一Peukcer)算法

    Douglas一Peukcer算法由D.Douglas和T.Peueker于1973年提出,简称D一P算法,是目前公认的线状要素化简经典算法.现有的线化简算法中,有相当一部分都是在该算法基础上进行改进 ...

  2. 道格拉斯-普克算法(Douglas–Peucker algorithm)

    道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算法.该算法的原 ...

  3. 道格拉斯-普克 Douglas-Peuker(DP算法)

    道格拉斯-普克抽稀算法,是用来对大量冗余的图形数据点进行压缩以提取必要的数据点. 该算法实现抽稀的过程是: 1)对曲线的首末点虚连一条直线,求曲线上所有点与直线的距离,并找出最大距离值dmax,用dm ...

  4. 【Python】道格拉斯-普克抽稀算法

    常用的地图点压缩 1.算法应用 道格拉斯-普克抽稀算法,是用来对大量冗余的图形数据点进行压缩以提取必要的数据点. 2.算法步骤 对每一条曲线的首末点虚连一条直线,求所有点与直线的距离, 并找出最大距离 ...

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

    1.算法说明   道格拉斯-普克算法 Douglas-Peucker Algorithm 简称 D-P 算法,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法,是将曲线近似表示为一系列点 ...

  6. opencv 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数

    凸包convexHull.道格拉斯-普克算法Douglas-Peucker algorithm.approxPloyDP 函数 道格拉斯-普克算法(Douglas–Peucker algorithm) ...

  7. OpenCV 学习笔记03 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数...

    凸形状内部的任意两点的连线都应该在形状里面. 1 道格拉斯-普克算法 Douglas-Peucker algorithm 这个算法在其他文章中讲述的非常详细,此处就详细撰述. 下图是引用维基百科的.ε ...

  8. matlab Douglas-Peucker 道格拉斯-普克算法

    c道格拉斯-普克算法 [1]  (Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算 ...

  9. 【图像处理】道格拉斯-普克算法(曲线的折线段逼近)

    目录 一.提要 二.为什么要道格拉斯-普克算法 三.算法描述 四.代码实现 4.1 Python代码1 4.2 python代码2 五.结论 该文的应用见文章:[Halcon算子]get_contou ...

最新文章

  1. linux6.6系统安装,CentOS6.6系统怎么安装
  2. python简单代码hello-[代码全屏查看]-python初学之helloworld
  3. mac下idea 13 在tomcat 7控制台乱码
  4. 输出链表中倒数第k个结点
  5. 全国软考数据库系统工程师教程(第2版)目录
  6. 35-面试:如何找出字符串的字典序全排列的第N种
  7. 日本的电视节目到底能有多特别?
  8. Linux as4开启telnet,Red hat AS4开启telnet过程
  9. php获取js函数返回的值_最全最详细的PHP面试题(带有答案)
  10. 动态规划——How to Type(hdu2577)
  11. linux 磁盘被挂载2个目录,Linux检测并挂载第二块硬盘的步骤
  12. Web 上构建MDI 应用程序---Prototype Window Class
  13. RobotFramework:App九宫格滑动解锁
  14. WINDOWS内核对象及其理解
  15. Line-in和Mic-in的区别和使用及Line-out
  16. 二叉树相关题(Java实现)
  17. 【PAT甲级 模拟 测试点0、3、4、5、7、8分析】1026 Table Tennis (30 分)
  18. 复利单利计算的功能解释
  19. Java 如何将线程挂起呢?
  20. android ppi,300ppi是人眼极限是断章取义_手机Android频道-中关村在线

热门文章

  1. 深度神经网络(DNN)的正则化
  2. 数学符号的读法和英文表示
  3. 多层神经网络(BP算法)介绍
  4. 苹果企业证书_企业签名App稳定吗?
  5. 2个字节能存多少个16进制_LabVIEW高级编程技巧:如何从内存字节流中恢复原始数据...
  6. k8s architecture
  7. 机器学习实战读书笔记(1)
  8. spring源码分析之@ImportSelector、@Import、ImportResource工作原理分析
  9. SOAP 及其安全控制--转载
  10. 13走了,14来了,新的一年,新的开始。