路径处理 | 关键点提取之Douglas–Peucker算法(附ROS C++/Python实现)

news2024/9/23 11:52:54

目录

  • 0 专栏介绍
  • 1 路径关键点提取
  • 2 道格拉斯-普克算法Douglas–Peucker
  • 3 算法实现与可视化
    • 3.1 ROS C++仿真
    • 3.2 Python仿真

0 专栏介绍

🔥课设、毕设、创新竞赛必备!🔥本专栏涉及更高阶的运动规划算法轨迹优化实战,包括:曲线生成、碰撞检测、安全走廊、优化建模(QP、SQP、NMPC、iLQR等)、轨迹优化(梯度法、曲线法等),每个算法都包含代码实现加深理解

🚀详情:运动规划实战进阶:轨迹优化篇


1 路径关键点提取

路径关键点提取也称为路径降采样,在路径规划中主要用于简化和优化路径表示。一方面,路径降采样可以去除冗余点,从而减少路径中的采样点数量,减小数据存储和传输的成本;另一方面,在路径跟踪和导航时,较少的点可以提高计算效率,减少实时处理的负担。在环境噪声敏感型的算法中,简化路径保留了路径的关键特征和形状,而滤除了噪点,可以增强在执行过程中对微小抖动或误差的鲁棒性

2 道格拉斯-普克算法Douglas–Peucker

道格拉斯-普克算法(Douglas–Peucker)是一种经典的路径关键点提取算法,其基于分治思想,以采样前后路径误差最小化为目标,提取路径关键点。

以下图为例阐述算法原理

  1. 初始给定一组有序的路径点列 { p } 0 N − 1 \left\{ \boldsymbol{p} \right\} _{0}^{N-1} {p}0N1与误差阈值 δ \delta δ,其中 N N N是路径点数;
    在这里插入图片描述

  2. 以路径首末点组成的 p 0 p N − 1 \boldsymbol{p}_0\boldsymbol{p}_{N-1} p0pN1为初始待处理线段,查找 p 0 p N − 1 \boldsymbol{p}_0\boldsymbol{p}_{N-1} p0pN1之间的点列中离 p 0 p N − 1 \boldsymbol{p}_0\boldsymbol{p}_{N-1} p0pN1最远的点,并判断该距离 d d d是否大于阈值 δ \delta δ,若 d > δ d>\delta d>δ则说明该点不能剪枝(否则剪枝前后曲线误差超过预期);若 d ≤ δ d \le \delta dδ则说明该点可以忽略;如图所示需要保留 p 3 \boldsymbol{p}_3 p3

在这里插入图片描述

  1. 对需要保留的节点进行分治,重复步骤(2)直到遍历结束;如图所示,分别以 p 0 p 3 \boldsymbol{p}_0\boldsymbol{p}_3 p0p3 p 3 p N − 1 \boldsymbol{p}_3\boldsymbol{p}_{N-1} p3pN1为待处理线段进行递归

在这里插入图片描述

  1. 最终得到剪枝后的路径点列如图所示

在这里插入图片描述

3 算法实现与可视化

3.1 ROS C++仿真

核心代码如下所示

void RDP::process(const rmp::common::geometry::Points2d& path_in, rmp::common::geometry::Points2d& path_out)
{
  path_out.clear();
  int max_idx = -1;
  double max_dist = -1.0;
  int path_size = static_cast<int>(path_in.size());
  rmp::common::geometry::LineSegment2d line({ path_in[0].x(), path_in[0].y() },
                                            { path_in[path_size - 1].x(), path_in[path_size - 1].y() });
  for (int i = 1; i < path_size - 1; i++)
  {
    double d = line.distanceTo({ path_in[i].x(), path_in[i].y() });
    if (d > max_dist)
    {
      max_dist = d;
      max_idx = i;
    }
  }

  if (max_dist > delta_)
  {
    rmp::common::geometry::Points2d left_pts, right_pts;
    left_pts.reserve(max_idx + 1);
    right_pts.reserve(path_size - max_idx);
    for (int i = 0; i <= max_idx; i++)
    {
      left_pts.emplace_back(path_in[i].x(), path_in[i].y());
    }
    for (int i = max_idx; i < path_size; i++)
    {
      right_pts.emplace_back(path_in[i].x(), path_in[i].y());
    }

    rmp::common::geometry::Points2d left_result, right_result;
    process(left_pts, left_result);
    process(right_pts, right_result);
    path_out.insert(path_out.end(), left_result.begin(), left_result.end() - 1);
    path_out.insert(path_out.end(), right_result.begin(), right_result.end());
  }
  else
  {
    path_out.emplace_back(path_in[0].x(), path_in[0].y());
    path_out.emplace_back(path_in[path_size - 1].x(), path_in[path_size - 1].y());
  }
}

我们用红色的原点表示路径点,绿色曲线段表示路径。下面显示的是未处理的路径点,因为地图栅格分辨率是 0.05 m 0.05m 0.05m,所以看起来非常稠密

在这里插入图片描述

经过算法剪枝后的路径如下所示,可以看到既保留了原始路径的几何特征,又大幅度降低了路径冗余度

在这里插入图片描述

3.2 Python仿真

核心代码如下所示:

def rdp_rec(M, epsilon, dist=pldist):
    dmax = 0.0
    index = -1

    for i in xrange(1, M.shape[0]):
        d = dist(M[i], M[0], M[-1])

        if d > dmax:
            index = i
            dmax = d

    if dmax > epsilon:
        r1 = rdp_rec(M[:index + 1], epsilon, dist)
        r2 = rdp_rec(M[index:], epsilon, dist)

        return np.vstack((r1[:-1], r2))
    else:
        return np.vstack((M[0], M[-1]))

完整工程代码请联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解并发原子性、可见性、有序性与JMM内存模型

1. 并发三大特性 并发编程Bug的源头&#xff1a;原子性、可见性和有序性问题 1.1 原子性 一个或多个操作&#xff0c;要么全部执行且在执行过程中不被任何因素打断&#xff0c;要么全部不执行。在 Java 中&#xff0c;对基本数据类型的变量的读取和赋值操作是原子性操作&…

HTB-GreenHorn 靶机笔记

GreenHorn 靶机笔记 概述 GreenHorn 是 HTB 上的一个 linux easy 难度的靶机&#xff0c;主要是通过信息搜集和代码审计找到对我们有用的信息。其中还包含了对pdf文件的修复技术 靶机地址&#xff1a;https://app.hackthebox.com/machines/GreenHorn 一丶 nmap 扫描 1&…

Spring Boot 学习之路 -- 基础认知

前言 最近因为业务需要&#xff0c;被拉去研究后端的项目&#xff0c;代码基于 Spring Boot&#xff0c;对我来说完全小白&#xff0c;需要重新学习研究…出于个人习惯&#xff0c;会以 Blog 文章的方式做一些记录&#xff0c;文章内容基本来源于「 Spring Boot 从入门到精通&…

Mac系统Docker中SQLserver数据库文件恢复记录

Mac系统Docker中SQLserver数据库文件恢复记录 Mac想要安装SQLsever&#xff0c;通过docker去拉去镜像是最简单方法。 一、下载Docker Docker 下载安装&#xff1a; 需要‘科学上网’ 才能访问到docker官网。&#xff08; https://docs.docker.com/desktop/install/mac-ins…

短剧APP分销小视频联盟收益源码带版权激励视频无需自己上传短剧

功能介绍&#xff1a; 带2000多部短剧资源&#xff0c;有版权&#xff0c;无需自己更新短剧&#xff0c; 已对接广告联盟&#xff0c;解锁短剧观看激励视频&#xff0c;对接各大广告平台 带刷小视频功能&#xff0c;插入视频广告&#xff0c;获取广告收益&#xff0c; 带任…

Stable Diffusion绘画 | ControlNet应用-instant-ID控制器:快速生成人物多角度图片

使用 instant-ID 控制器&#xff0c;用户只需要提供一张正脸图片&#xff0c;就可以快速地给人物生成多角度图片的&#xff0c;从而很好的保持了人物的一致性。 对于要制作小说推文、创建人物故事情节的创作&#xff0c;是一个非常好用且高效的功能。 准备工作 使用该控制类型&…

什么是端到端(end to end)大模型,它和传统的大模型有什么区别?其优势与劣势是什么?

“ 端到端模型&#xff0c;是一个直接由输入获取输出的过程 ” 最近有一个很火的关于人工智能模型的词——端到端模型。 那么什么是端到端模型&#xff1f;为什么会提出端到端模型&#xff0c;以及它解决了哪些问题&#xff1f; 今天我们就来一起了解一下这个端到端模型。 …

如何使用ChatGPT撰写文献综述?7个步骤轻松搞定

大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾学术科研AI实操的学术人。关于使用ChatGPT等AI学术科研的相关问题可以和作者七哥(yida985)交流,多多交流,相互成就,共同进步,为大家带来最酷最有效的智能AI学术科研写作攻略。 撰写文献综述对于研究人员和学生来说…

ssm汉服文化平台网站

专业团队&#xff0c;咨询就送开题报告&#xff0c;欢迎大家咨询&#xff0c;联系方式在文章底部 摘 要 本论文主要论述了如何使用JAVA语言开发一个汉服文化平台网站 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象…

【题解】—— LeetCode一周小结38

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结37 16.公交站间的距离 题目链接&#xff1a;1184. 公交站间的距…

【Linux】入门【更详细,带实操】

Linux全套讲解系列&#xff0c;参考视频-B站韩顺平&#xff0c;本文的讲解更为详细 目录 1、课程内容 2、应用领域 3、概述 4、 Linux和Unix 5、VMware15.5和CentOS7.6安装 6、网络连接三种方式 7、虚拟机克隆 8、虚拟机快照 9、虚拟机迁移删除 10、vmtools 11、目录…

抱歉占用公共资源,大家别猜啦,我们在一起了@Yaker

家人们上午好呀 这里是超绝脱单牛一枚 没错&#xff0c;我和Yaker有一个孩子&#xff08;bushi 今天我们的孩子YakLang来给大家介绍介绍&#xff0c;ta对块作用域的处理方式 在编程中&#xff0c;作用域&#xff08;Scope&#xff09;指的是变量、函数和对象的可访问性和生命…

文件查找和打包压缩【1.7】

文件查找和打包压缩【1.7】 八、文件查找和打包压缩8.1 文件查找8.1.1 locate8.1.2 findfind8.1.2.1 指定搜索目录层级8.1.2.2 先处理文件再处理目录8.1.2.3 根据文件名和inode查找8.1.2.4 根据属主属组查找8.1.2.5 根据文件类型查找8.1.2.6 空文件或目录8.1.2.7 组合条件8.1.2…

Vue项目之Element-UI(Breadcrumb)动态面包屑效果 el-breadcrumb

效果预览 需要导航的页面Vue.js 最笨的方法就是在每个需要面包屑的页面中固定写好 <template><div class="example-container"><el-breadcrumb separator="/"

不再错过任何一个区块!用Node.js + WebSocket轻松实现区块链实时监控

文章目录 前言一、WebSocket是什么&#xff1f;二、项目结构三、代码实现1. 后端实现2. 前端实现 四、启动项目总结 前言 随着区块链技术的发展&#xff0c;实时监控区块链网络中的区块和交易信息变得越来越重要。无论是开发去中心化应用&#xff08;DApp&#xff09;&#xf…

【WebGIS实例】(17)下载瓦片底图并实现离线加载——以天地图为例

前言 在有些项目中&#xff0c;会有部署到无法访问互联网的内网环境中&#xff0c;这时候就会有离线部署应用和地图服务等需求了。 本博客是本着交流学习的目的&#xff0c;分享一个离线瓦片地图的获取方案&#xff0c;以天地图为案例&#xff0c;实现步骤&#xff1a; 安装…

读书笔记——DDIA-v2 设计数据密集型应用(第二版)

ddia-v2中文版地址&#xff1a;https://github.com/Vonng/ddia/tree/v2 ddia-v2看完感觉爱不释手&#xff0c;只要是数据相关的知识都娓娓道来&#xff0c;为什么会这样&#xff1f;现在是怎样的&#xff1f;这样有什么问题&#xff1f;其中的看法和想法实在精辟、干练&#xf…

典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式

先看代码与实现&#xff1a; 文件结构 triangle_area4.jsp <% page contentType"text/html;charsetUTF-8" pageEncoding"UTF-8" %> <html> <body> <%--<jsp:useBean>&#xff1a;用于在JSP中实例化JavaBean。在这里&#xff0c…

感知笔记1:ROS 视觉- 跟随红球

- 目录 - 如何在 ROS 中可视化 RGB 相机。如何作为机器人切换主题。如何创建 blob 检测器。如何获取要跟踪的颜色的颜色编码。如何使用 blob 检测数据并移动 RGB 相机以跟踪 blob。 机器人技术中最常见的传感器是不起眼的 RGB 摄像头。它用于从基本颜色跟踪&#xff08;blob 跟…

解决 TortoiseGitPlink Fatal Error:深入解析

解决 TortoiseGitPlink Fatal Error&#xff1a;深入解析 在 Windows 平台上&#xff0c;开发者使用 Git 和 TortoiseGit 进行版本控制时&#xff0c;有时会遇到 TortoiseGitPlink Fatal Error。该错误通常是在推送/拉取代码时&#xff0c;客户端未能提供正确的 SSH 密钥。 1…