170316.道格拉斯-普克算法
道格拉斯-普克算法
道格拉斯-普克算法 (Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法、迭代适应点算法、分裂与合并算法)是乌尔斯·拉默(Urs Ramer)于1972年以及大卫·道格拉斯(David Douglas)和托马斯·普克(Thomas Peucker)于1973年提出的一种简化线的一种经典算法。
它是通过减少曲线中点的数量,得出一条尽可能完整的表达原有曲线的特征的曲线。
一般来讲,道格拉斯-普克算法需要一个极差D,极差D的值越大,证明曲线简化的越多,反之极差越小,表示简化的越小
通俗的理解,道格拉斯-普克算法是通过分治策略处理一组曲线,而极差D则可以理解为一个比较值,或者可以说是一个临界点,通过对垂距大于此临界点的点进行保留,对小于此临界点的点进行删除,达到简化曲线的效果
算法的基本思路是:
对曲线的首末点虚连一条直线,求此曲线其余所有点到直线的距离(垂距),从中找出最大距离值dmax ,用dmax与限差D相比:若dmax <D,这条曲线上的中间点全部舍去;若dmax ≥D,保留dmax 对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法,当曲线无法分为两部分时结束。
具体步骤如下:
(1) 在曲线首尾两点间虚连一条直线,求出其余各点到该直线的距离。
(2)选其最大者与极差D相比较,若大于极差D,则离该直线距离最大的点保留,否则将直线两端点间各点全部舍去。
(3)以保留的点为中心,将已知曲线分成两部分处理,重复执行第1、2步操作,迭代操作,即仍选该直线距离最大者与极差D比较,依次取舍,直到无点可舍去,最后得到满足给定精度限差为D的曲线点坐标
具体的实现过程如下图(此图来自于网络)
在计算最大距离的时候(垂距),一般来讲,我们知道三个点的坐标,两个坐标点形成得直线,求另一个坐标点到此直线的距离。
一般来讲,行列式算法,海伦公式,向量法,都可以求出面积;
这里介绍下行列式算法:
已知三个点坐标(x1,y1),(x2,y2),(x3,y3)
由此三角形构成的面积是|S|注意是S的绝对值,因为坐标的方向不确定。
下面是S的求值
求出面积后,用面积公式,得到高(垂距),找出所有点中垂距的最大值与极差D比较。
下面简要写出道格拉斯-普克算法的代码,由于是采用传统的迭代方法,存在一定的弊端
qt代码如下:
#include <QPoint>
#include <QVector>
/**
* @brief CPointRarefyOprt::PerpendicularDistance 计算点到首尾连线间的距离(垂距)
* @param Point1 首坐标
* @param Point2 尾坐标
* @param Point 要计算到直线距离的点
* @return
*/
double PerpendicularDistance(const QPoint &Point1, const QPoint &Point2, const QPoint &Point)
{
//行列式算法的展开
double area = fabsf(0.5 * (Point1.x * Point2.y + Point2.x * Point.y + Point.x * Point1.y - Point2.x * Point1.y - Point.x * Point2.y - Point1.x * Point.y));
double bottom = sqrtf(pow(Point1.x - Point2.x, 2) + pow(Point1.y - Point2.y, 2));
double height = area / bottom * 2;
return height;
}
/**
* @brief DouglasPeuckerReduction 道格拉斯——普克算法
* @param Points 要进行简化的曲线的点列
* @param startPoint 进行此算法的曲线开始的点的数组下标
* @param endPoint 进行此算法的曲线结束的点的数组下标
* @param tolerance 极差D(阈值)
* @param resultPoints 得到的简化的曲线
*/
void DouglasPeuckerReduction(QVector<QPoint> Points,int startPoint
,int endPoint, double tolerance,QVector<QPoint> resultPoints)
{
double maxDistance = 0; //最远距离(垂距)
int indexFarthest = -1; //最远距离点的数组下标
if(endPoint-startPoint<=1)
{
if(endPoint==startPoint)
{
//endPoint==startPoint相等时,只有一个点时,所以添加一个点
resultPoints.append(points[startPoint]);
}
else
{
//有两个点时,添加两个点
resultPoints.append(points[startPoint]);
resultPoints.append(points[endPoint]);
}
//当小于等于两个点时,直接返回
return;
}
for (int index = startPoint; index < endPoint; index++)
{
double distance = PerpendicularDistance(points[startPoint],points[endPoint],points[index]);
if (distance > maxDistance)
{
//当新得到的点的垂距大于之前的最大垂距时,更新最大垂距,并且更新最大垂距点的下标
maxDistance = distance;
indexFarthest = index;
}
}
if (maxDistance > tolerance && indexFarthest != -1)
{
//对起始点到最大垂距点之间的点重复进行道格拉斯——普克算法
DouglasPeuckerReduction(points, startPoint,indexFarthest-1, tolerance, resultPoints);
//将最大垂距点保留
resultPoints.append(points[indexFarthest]);
//对最大垂距点到结束点之间的点重复进行道格拉斯——普克算法
DouglasPeuckerReduction(points, indexFarthest+1,endPoint, tolerance, resultPoints);
}
return;
} //第一次写博客,以前一直想写,但总不知道写些什么,或者感觉想写的东西太过于简单,或者感觉想写的东西自己无法合理的表示//写这个东西用了两个多小时,借鉴了一些文档,但其中还是不免有许多错误,求指点,感激不尽//或许很简单,或许很多错误,但是当我鼓足勇气写完之后,忽然发现,原来坚持写比什么都重要
转载于:https://www.cnblogs.com/wpch1993/p/6558086.html
170316.道格拉斯-普克算法相关推荐
- c++多边形扫描线填充算法_基于MATLAB的道格拉斯普克算法递归实现
道格拉斯普克算法 (道格拉斯-普克)Douglas-Peukcer算法由D.Douglas和T.Peueker于1973年提出,是线状要素抽稀的经典算法.用它处理大量冗余的几何数据点,既可以达到数据量 ...
- opencv 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数
凸包convexHull.道格拉斯-普克算法Douglas-Peucker algorithm.approxPloyDP 函数 道格拉斯-普克算法(Douglas–Peucker algorithm) ...
- OpenCV 学习笔记03 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数...
凸形状内部的任意两点的连线都应该在形状里面. 1 道格拉斯-普克算法 Douglas-Peucker algorithm 这个算法在其他文章中讲述的非常详细,此处就详细撰述. 下图是引用维基百科的.ε ...
- 基于道格拉斯普克算法的轮廓点简化
道格拉斯普克算法(DP)对元素进行简化,这里介绍对轮廓点进行简化,如下图展示了轮廓点提取.DP保留的关键点.关键点生成的矢量线: 简化点连接生成的多边形 DP简化轮廓点后的关键点 关键点相连生成的 ...
- 道格拉斯-普克算法(Douglas–Peucker algorithm)
道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算法.该算法的原 ...
- matlab Douglas-Peucker 道格拉斯-普克算法
c道格拉斯-普克算法 [1] (Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算 ...
- 道格拉斯-普克算法(经纬度或坐标点抽稀)
起因 最近在做一个车联网项目,有一个场景是车辆定时上报当前所在经纬度等位置信息上报给平台,平台通过web页面在高德地图上展示车辆行驶路径. 由于车辆上报规则是每隔4s上报一次,一个小时也就是900个点 ...
- 【图像处理】道格拉斯-普克算法(曲线的折线段逼近)
目录 一.提要 二.为什么要道格拉斯-普克算法 三.算法描述 四.代码实现 4.1 Python代码1 4.2 python代码2 五.结论 该文的应用见文章:[Halcon算子]get_contou ...
- C语言程序实现道格拉斯—普克算法(Douglas--Peucker)
算法简介 道格拉斯-普克算法(Douglas-Peucker)也称,线简化算法.作用在于,删除冗余数据,减少数据的存贮量,节省存贮空间,加快后继处理的速度. 格拉斯-普克算法(Douglas-Peuc ...
最新文章
- javascript数组集锦
- html wbr标签,HTML wbr标签
- redis 漏洞利用与防御
- 160. Intersection of Two Linked Lists
- MongoDB存储文件之GridFS
- 深入理解Three.js(WebGL)贴图(纹理映射)和UV映射
- 短网址PHP源码Shortny
- 不要再使用JS框架了
- jvm虚拟机创建对象
- 搜索引擎只能抓取html文件,为什么有些明明存在的网页不能被搜索到?
- 初级通信工程师考试教程:电信网的划分
- [转]420个JS网页特效
- 短信接口的功能及适用范围
- DongDong数颜色 树状数组,dfs序,统计区间不同数字个数
- 基于相似性网络融合的目标分类研究
- D-Link DCS系列监控账号密码信息泄露
- win10系统无法正常自动启动服务
- 货币金融学——金融体系监管
- Undetected
- Java中Lambda表达式使用及详解
热门文章
- u盘排序软件_华硕电脑u盘启动设置
- int** 赋值_Python的赋值、浅拷贝、深拷贝之间的区别
- php文件教程,php的文件上传入门教程(实例讲解)
- php try catch 作用域,php作用域
- python 字符串去重且相同字符最多出现2次_Python实现计算字符串中出现次数最多的字符示例...
- amd 深度学习模型部署_Web服务部署深度学习模型-续集
- java与c 通信_Java与C之间的socket通信
- (六) shiro在web中自定义Realm
- java面试题二十八 从未用过的 native
- log4j 调试时候配置