Douglas Peucker算法的C#实现
一、算法原理
Douglas-Peucker算法
在数字化过程中,需要对曲线进行采样简化,即在曲线上取有限个点,将其变为折线,并且能够在一定程度
上保持原有的形状。
经典的Douglas-Peucker算法描述如下:
(1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦;
(2)得到曲线上离该直线段距离最大的点C,计算其与AB的距离D;
(3)比较该距离与预先给定的阈值threshold的大小,如果小于threshold,则该直线段作为曲线的近似,该段曲线处理完毕。
(4)如果距离大于阈值,则用C将曲线分为两段AC和BC,并分别对两段取信进行1~3的处理。
(5)当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似。
二、算法C#实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication2
{
public struct cvPoint
{
public int X;
public int Y;
public cvPoint(int x, int y)
{
X = x;
Y = y;
}
}
class Program
{
static void Main(string[] args)
{
var points = new List<cvPoint>();
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
var epsilon = 0.8d;
var filteredPoints = new List<cvPoint>();
DouglasPeucker(points, epsilon, ref filteredPoints);
Console.WriteLine("Filtered points:");
foreach (var f in filteredPoints)
{
Console.WriteLine(string.Format("{0},{1}", f.X, f.Y));
}
Console.ReadKey();
}
private static double distanceToSegment(cvPoint p, cvPoint start, cvPoint end)
{
var m1 = ((double)(end.Y - start.Y)) / ((double)(end.X - start.X));
var c1 = start.Y - m1 * start.X;
var interPointX = 0d;
var interPointY = 0d;
if (m1 == )
{
interPointX = p.X;
interPointY = c1; }
else
{
var m2 = - / m1;
var c2 = p.Y - m2 * p.X;
interPointX = (c1 - c2) / (m2 - m1);
interPointY = m2 * interPointX + c2;
}
return Math.Sqrt(Math.Pow(p.X - interPointX, ) + Math.Pow(p.Y - interPointY, ));
} private static void DouglasPeucker(IList<cvPoint> PointList, double epsilon, ref List<cvPoint> filteredPoints)
{
var dmax = 0d;
int index = ;
int length = PointList.Count;
for (int i = ; i < length - ; i++)
{
var d = distanceToSegment(PointList[i], PointList[], PointList[length - ]);
Console.WriteLine(string.Format("{0}.distence:{1}", i, d));
if (d > dmax)
{
index = i;
dmax = d;
}
}
Console.WriteLine(string.Format("dMax:{0}", dmax));
// If max distance is greater than epsilon, recursively simplify
if (dmax > epsilon)
{
filteredPoints.Add(PointList[]);
filteredPoints.Add(PointList[index]);
filteredPoints.Add(PointList[length - ]);
DouglasPeucker(PointList.Take(index + ).ToList(), epsilon, ref filteredPoints);
DouglasPeucker(PointList.Skip(index + ).Take(PointList.Count - index - ).ToList(), epsilon, ref filteredPoints);
}
}
}
}
三、算法验证
近似前:

近似后的线段:


本文地址: http://www.cnblogs.com/deepleo/p/Douglas-Peucker.html
参考:http://www.codeproject.com/Articles/18936/A-C-Implementation-of-Douglas-Peucker-Line-Approxi
Douglas Peucker算法的C#实现的更多相关文章
- OpenCV 学习笔记03 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数
凸形状内部的任意两点的连线都应该在形状里面. 1 道格拉斯-普克算法 Douglas-Peucker algorithm 这个算法在其他文章中讲述的非常详细,此处就详细撰述. 下图是引用维基百科的.ε ...
- 盘点十大GIS相关算法
1.道格拉斯-普克算法(Douglas–Peucker) 道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法)是将曲 ...
- GIS原理学习目录
GIS原理学习目录 内容提要 本网络教程是教育部“新世纪网络课程建设工程”的实施课程.系统扼要地阐述地理信息系统的技术体系,重点突出地理信息系统的基本技术及方法. 本网络教程共分八章:第一章绪论,重点 ...
- 利用道格拉斯·普客法(DP法)压缩矢量多边形(C++)
1.算法描述 经典的Douglas-Peucker算法(简称DP法)描述如下: (1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦: (2)得到曲线上离该直线段距离最大的点C,计算其与A ...
- 道格拉斯—普克(Douglas一Peukcer)节点抽稀算法
Douglas一Peukcer算法由D.Douglas和T.Peueker于1973年提出,简称D一P算法,是眼下公认的线状要素化简经典算法.现有的线化简算法中,有相当一部分都是在该算法基础上进行改进 ...
- OOP: One pont of view of OOP与基于算法设计的区别
..摘自<C++网络编程 卷1:运用ACE和模式消除复杂性> <C++ Network Programming Volume 1 Mastering Complexity with ...
- 推些C语言与算法书籍
c语言系统学习与进阶: 1. C primer plus C primer plus 作为一本被人推崇备至的 c 入门经典,C primer plus 绝非浪得虚名.应该 算得上 C 教材里最好的入门 ...
- 每周荐书:云原生、Docker、Web算法(评论送书)
每周荐书:云原生.Docker.Web算法(评论送书) 感谢大家对每周荐书栏目的支持,先公布下上周中奖名单 名优秀评论可以免费获得此书. 云原生应用架构实践 云原生架构,关注简化开发流程.提升研发 ...
- 图像处理之增强---图像增强算法四种,图示与源码,包括retinex(ssr、msr、msrcr)和一种混合算法
申明:本文非笔者原创,原文转载自:http://blog.csdn.net/onezeros/article/details/6342661 两组图像:左边较暗,右边较亮 第一行是原图像,他们下面是用 ...
随机推荐
- [洛谷P2420] 让我们异或吧
题目链接:让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是 ...
- Quartus ModelSim联合仿真中的RAM初始化
Modelsim只支持Hex格式的初始化文件,文件需要放在仿真的根目录下,例如:.\simulation\modelsim:并且在利用Quartus宏生成IP时,选择的初始化文件必须用绝对路径!否则M ...
- 【hdu1712】分组背包(每组最多选1个)
[分组背包] [题意]ACboy要开始选课了,上一门课能够获得的收益和他上这门课的时间是有关的,然后给你若干门课,让你帮他进行选课,每一门课自然是只能选择一个课程时长,问你如何选择,才能使ACboy获 ...
- [POJ2774]Long Long Message 解题报告
Long Long Message Description The little cat is majoring in physics in the capital of Byterland. A p ...
- swift中的尾随闭包的用法
尾随闭包就是这个函数的最后一个参数是一个闭包,所以规定这个闭包既可以写在函数的参数括号里面,也可以直接放在最后面来使用,就像重新给这个函数定义了一次一样,有些怪,不过用的时候,可以把闭包写在外面的.这 ...
- HDU 1162 Eddy's picture (最小生成树 普里姆 )
题目链接 Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to be ...
- Django-models,继承AbstractUser类
1.UserInfo类继承了Django模型自带的User类,需要导入AbstractUser 2.然后在settings.py中配置
- Tomcat下载安装及常见问题解决办法
一.Tomcat的下载: 下载地址:http://tomcat.apache.org/ 下载Tomcat6.0(在左侧的Download下,考虑到稳定性现在企业大部分还在用Tomcat6.0) (1) ...
- Nightmare安装and一个小例子
前端的功能测试 官方说法A high-level browser automation library,翻译过来就是高级浏览器自动化库 常用于UI测试和爬网 功能测试必须在真正浏览器做,现在有四种方法 ...
- [ Openstack ] Openstack-Mitaka 高可用之 计算服务(Nova)
目录 Openstack-Mitaka 高可用之 概述 Openstack-Mitaka 高可用之 环境初始化 Openstack-Mitaka 高可用之 Mariadb-Galera集群 ...