随机采样一致性算法RANSAC

点云分割

图片

图自:https://openaccess.thecvf.com/content_cvpr_2017/papers/Qi_PointNet_Deep_Learning_CVPR_2017_paper.pdf《PointNet:用于3D分类和分割的点集深度学习》

点云分割(Point Cloud Segmentation)是计算机视觉和3D图像处理中的一个重要步骤,通过将点云数据划分成有意义的子集,以便于进一步分析和处理。点云分割可以帮助识别和提取场景中的特定对象或区域,例如建筑物、道路、车辆等。这对于各种应用场景如自动驾驶、3D建模、机器人导航等都至关重要。

图片

图自:https://openaccess.thecvf.com/content_cvpr_2017/papers/Qi_PointNet_Deep_Learning_CVPR_2017_paper.pdf《PointNet:用于3D分类和分割的点集深度学习》

点云平面分割是从激光扫描仪获取的无序点云自动重建室内和城市环境的基本任务。作为最常见的平面分割方法之一,随机采样一致性 (RANSAC) 通常用于连续检测一个又一个的平面。

为什么要进行点云分割?

进行点云分割的主要原因有以下几点:

  1. 简化数据处理:分割后的点云数据更易于处理和分析,减少了计算复杂度。

  2. 提高识别精度:通过分割,将不同对象从点云中分离出来,有助于提高对象识别和分类的准确性。

  3. 增强应用效果:在实际应用中,分割后的点云可以更好地用于3D建模、环境感知、物体检测等任务,提高应用效果和实用性。

RANSAC算法发展历史

RANSAC(Random Sample Consensus,随机抽样一致性)算法由Fischler和Bolles于1981年提出,是一种通过随机抽样找到数据中的模型参数的算法。RANSAC在处理含有大量噪声和离群点的数据时,表现尤为出色。该算法的核心思想是反复从数据集中随机抽取样本,估计模型参数,并通过评估一致性来选择最优模型。尽管RANSAC已经有40多年的历史,但其简单有效的特性使其在点云分割、图像匹配、平面拟合等领域依然广泛应用。

算法概述

Fischler 和 Bolles 提出的 RANdom SAmple Consensus (RANSAC) 算法 [1] 是一种通用的参数估计方法,旨在应对输入数据中大量离群值。与许多从统计学文献中被计算机视觉社区采用的常见鲁棒估计技术(如 M-估计和最小中值平方)不同,RANSAC 是由计算机视觉社区内部开发的。

RANSAC 是一种重采样技术,通过使用估计基础模型参数所需的最小观察数(数据点)来生成候选解决方案。正如 Fischler 和 Bolles [1] 指出,与使用尽可能多的数据来获得初步解决方案然后剔除离群值的传统采样技术不同,RANSAC 使用最小的可能集合,然后使用一致的数据点扩展这个集合 [1]。

基本算法RANSAC概述如下:

  1. 随机选择确定模型参数所需的最小点数。

  2. 求解模型参数。

  3. 确定所有点集中有多少点符合预定的容差 。

  4. 如果集合中内点的数量与总点数的比例超过预定阈值 ,则使用所有识别的内点重新估计模型参数并终止。

  5. 否则,重复步骤 1 到 4(最多  次)。

迭代次数  的选择足够高,以确保至少有一个随机样本集不包含离群值的概率 (通常设为 0.99)。设  表示任何选定数据点为内点的概率, 表示观察到离群值的概率。需要进行  次最小点数  的迭代,其中

因此,通过一些操作得到:

有关基本 RANSAC 公式的更多详细信息,请参见 [1, 2]。RANSAC 的扩展包括使用最大似然框架 [4] 和重要性采样 [3]。

原文参见:https://www.cse.yorku.ca/~kosta/CompVis_Notes/ransac.pdf

RANSAC算法的数学原理可以概括如下:

  1. 随机抽样:从点云数据中随机选择若干点作为样本。

  2. 模型拟合:使用选定的样本点拟合模型。

  3. 一致性检验:计算拟合模型的所有点的误差,确定与模型一致的点(内点)。

  4. 模型优化:重复上述步骤多次,选择内点最多的模型作为最终模型。

假设我们要拟合一个平面模型,平面方程为:

RANSAC的具体步骤如下:

  1. 从点云数据中随机选择三个点,设为,  和。

  2. 计算平面模型参数 , ,  和 :

  3. 计算所有点到该平面的距离,根据距离判断是否为内点。

  4. 重复上述步骤,选择内点最多的平面模型作为最终结果。

图片

图片

图片

图片

图片

图片

图片

图片

图片



应用领域和场景

RANSAC算法在各种应用领域中得到了广泛应用,主要包括:

图片

https://isprs-annals.copernicus.org/articles/IV-2/1/2018/isprs-annals-IV-2-1-2018.pdf《H-RANSAC: A HYBRID POINT CLOUD SEGMENTATION COMBINING 2D AND 3D DATA》

  • 3D建模:用于从点云数据中提取建筑物、道路等结构

https://ieeexplore.ieee.org/document/7989159/

  • 自动驾驶:在环境感知中,RANSAC用于分割和识别道路、障碍物等。

图片

https://openaccess.thecvf.com/content/CVPR2023W/PVUW/papers/Sakaino_PanopticRoad_Integrated_Panoptic_Road_Segmentation_Under_Adversarial_Conditions_CVPRW_2023_paper.pdf

  • 机器人导航:帮助机器人识别和避开障碍物,提高导航精度。

  • 图像处理:用于图像配准、平面拟合等任务。

图片

https://www.cs.princeton.edu/courses/archive/fall11/cos495/COS495-Lecture11-LineExtraction.pdf

基于Python的可视化算法实例

下面是一个基于Python实现RANSAC点云分割的简单示例,点云数据均可在网址上获取(https://towardsdatascience.com/3d-model-fitting-for-point-clouds-with-ransac-and-python-2ab87d5fd363):

import random  # 导入用于生成随机数的库
import numpy as np  # 导入用于科学计算的库
import matplotlib.pyplot as plt  # 导入用于数据可视化的库
from sklearn.neighbors import KDTree  # 导入用于快速最近邻搜索的KDTree实现
from mayavi import mlab  # 导入用于3D数据可视化的库# 选择数据集路径
data_file = r"D:\系统默认\桌面\协作文件夹\Open3d python三维点云学习资料\the_researcher_desk.xyz"  # 请替换为你的数据文件路径# 读取点云数据
pcd = np.loadtxt(data_file, skiprows=1)  # 读取点云数据文件,跳过第一行# 分离几何属性和辐射属性
xyz = pcd[:, :3]  # 提取前三列作为几何属性(x, y, z坐标)
rgb = pcd[:, 3:6]  # 提取后三列作为辐射属性(颜色值)# 可视化点云(2D视图)
plt.figure(figsize=(8, 5), dpi=150)  # 创建一个8x5英寸,150dpi的图形
plt.scatter(xyz[:, 0], xyz[:, 1], c=rgb/255, s=0.05)  # 绘制散点图,颜色为rgb值,点大小为0.05
plt.title("Top-View")  # 设置图形标题
plt.xlabel('X-axis (m)')  # 设置x轴标签
plt.ylabel('Y-axis (m)')  # 设置y轴标签
plt.show()  # 显示图形# 使用Mayavi进行3D可视化
mlab.points3d(xyz[:, 0], xyz[:, 1], xyz[:, 2], xyz[:, 2], mode="point", colormap='viridis')  # 使用Mayavi绘制3D点云,颜色为高度(z值)
mlab.title("Point Cloud Visualization")  # 设置图形标题
mlab.colorbar(title='Height', orientation='vertical')  # 添加颜色条,表示高度
mlab.show()  # 显示图形# 设置RANSAC参数
threshold = 0.05  # 设置点到平面的距离阈值
iterations = 1000  # 设置RANSAC算法的迭代次数# 自动设置参数
tree = KDTree(np.array(xyz), leaf_size=2)  # 使用KDTree进行最近邻搜索,加速计算
nearest_dist, nearest_ind = tree.query(xyz, k=8)  # 查询每个点的8个最近邻点
avg_distance = np.mean(nearest_dist[:, 1:])  # 计算平均距离,忽略自身距离
threshold = avg_distance * 10  # 设置新的距离阈值为平均距离的10倍# RANSAC 平面检测函数
def ransac_plane(xyz, threshold=0.05, iterations=1000):inliers = []  # 初始化内点列表n_points = len(xyz)  # 获取点云的点数i = 0  # 初始化迭代计数器while i < iterations:  # 迭代进行RANSACidx_samples = random.sample(range(n_points), 3)  # 随机选择3个点pts = xyz[idx_samples]  # 获取这3个点的坐标vecA = pts[1] - pts[0]  # 计算向量AvecB = pts[2] - pts[0]  # 计算向量Bnormal = np.cross(vecA, vecB)  # 计算法向量a, b, c = normal / np.linalg.norm(normal)  # 归一化法向量d = -np.sum(normal * pts[1])  # 计算平面方程的d值distance = (a * xyz[:, 0] + b * xyz[:, 1] + c * xyz[:, 2] + d) / np.sqrt(a ** 2 + b ** 2 + c ** 2)  # 计算所有点到平面的距离idx_candidates = np.where(np.abs(distance) <= threshold)[0]  # 找到所有符合距离阈值的点(内点)if len(idx_candidates) > len(inliers):  # 如果当前内点数量大于之前的最大内点数量equation = [a, b, c, d]  # 更新平面方程参数inliers = idx_candidates  # 更新内点列表i += 1  # 迭代计数器加1return equation, inliers  # 返回平面方程参数和内点列表# 执行RANSAC
eq, idx_inliers = ransac_plane(xyz, threshold, iterations)  # 调用RANSAC平面检测函数
inliers = xyz[idx_inliers]  # 获取内点坐标# 获取外点
mask = np.ones(len(xyz), dtype=bool)  # 创建一个全为True的布尔数组
mask[idx_inliers] = False  # 将内点位置设置为False
outliers = xyz[mask]  # 获取外点坐标# 可视化结果(Matplotlib)
ax = plt.axes(projection='3d')  # 创建一个3D绘图对象
ax.scatter(inliers[:, 0], inliers[:, 1], inliers[:, 2], c='cornflowerblue', s=0.02)  # 绘制内点,颜色为淡蓝色
ax.scatter(outliers[:, 0], outliers[:, 1], outliers[:, 2], c='salmon', s=0.02)  # 绘制外点,颜色为鲑鱼色
plt.show()  # 显示图形# 导出结果
result_folder = r"D:\系统默认\桌面\python三维点云学习资料\RESULTS"  # 设置结果保存路径
np.savetxt(result_folder + "inliers.xyz", inliers, fmt='%1.4f', delimiter=';')  # 保存内点坐标
np.savetxt(result_folder + "outliers.xyz", outliers, fmt='%1.4f', delimiter=';')  # 保存外点坐标

通过上述代码,我们可以将点云数据中的平面部分(例如桌面、地板等)分割出来,并以不同颜色进行可视化。这种分割方法不仅简化了后续处理步骤,还能显著提高对象识别的精度和效率。

可视化 1:Matplotlib 2D视图

提供点云数据的2D平面视图,从而快速了解数据的分布和结构。

图片

实现方式:

  • 使用 matplotlib.pyplot 创建一个2D散点图,展示点云数据的X和Y坐标。

  • 使用颜色 (c=rgb/255) 表示点的辐射属性(颜色值)。

  • 设置图形的大小、分辨率和标题。

表现内容:

  • 从上方观察的点云数据平面视图(Top-View)。

  • X轴和Y轴表示点的平面位置,颜色则提供了点的辐射属性信息。

  • 该视图有助于识别数据中的密集区域、异常点和总体分布趋势。

可视化 2:Mayavi 3D视图

提供点云数据的交互式3D视图,使用户能够从多个角度查看数据并理解其空间结构。

图片

实现方式:

  • 使用 mayavi.mlab 创建一个3D散点图,展示点云数据的X、Y和Z坐标。

  • 颜色渐变表示点的高度(Z轴),使用 colormap='viridis' 设定颜色映射。

  • 添加颜色条(colorbar)以表示高度信息。

表现内容:

  • 点云数据的3D视图,用户可以通过旋转和缩放来观察数据的三维结构。

  • 颜色表示高度(Z轴),使得不同高度的点可以通过颜色轻松区分。

  • 该视图提供了全面的空间结构理解,有助于识别数据的高低变化和总体形状。

可视化 3:Matplotlib 3D视图(分割结果)

图片

展示通过RANSAC算法分割后的点云数据,区分内点和外点。

实现方式:

  • 使用 matplotlib.pyplot 创建一个3D散点图,分别展示内点和外点的X、Y和Z坐标。

  • 内点(符合平面模型的点)使用淡蓝色(cornflowerblue)表示,外点(不符合平面模型的点)使用鲑鱼色(salmon)表示。

  • 通过不同颜色区分内点和外点。

表现内容:

  • 分割后的点云数据3D视图,清晰展示了内点和外点的空间分布。

  • 内点和外点的颜色区分使得用户能够直观地看到哪些点符合平面模型,哪些点为异常点或噪声。

  • 该视图有助于评估RANSAC算法的效果,理解数据的分割情况。

该代码实现了从点云数据文件中读取数据,进行预处理和可视化,并通过RANSAC算法进行平面检测。具体流程包括:1)读取和分离点云数据的几何和辐射属性,2)使用Matplotlib进行2D和3D数据可视化,3)使用Mayavi进行3D可视化以展示点云的高度信息,4)使用KDTree加速最近邻搜索,5)基于自动计算的阈值和迭代次数运行RANSAC算法,检测平面并识别内点和外点,6)最终可视化分割结果并保存内点和外点数据到文件中。

以上内容总结自网络,如有帮助欢迎关注与转发,我们下次再见!

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

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

相关文章

数据结构——位图布隆过滤器

一、位图 1.1 概念 所谓位图&#xff0c;就是用每一位来存放某种状态&#xff0c;适用于海量数据&#xff0c;数据无重复的场景。通常是用来判断某个数据存不存在的。 数据是否在给定的整形数据中&#xff0c;结果是在或者不在&#xff0c;刚好是两种状态&#xff0c;那么可以…

Android获取当前屏幕显示的是哪个activity

在 Android 中&#xff0c;要获取当前屏幕显示的 Activity&#xff0c;可以使用以下几种方法&#xff1a; 方法一&#xff1a;使用 ActivityManager 获取当前运行的任务信息 这是一个常见的方法&#xff0c;尽管从 Android 5.0 (API 21) 开始&#xff0c;有些方法变得不太可靠…

【多线程】线程安全的单例模式

文章目录 什么是单例模式饿汉实现方式饿汉实现模式的特点 懒汉实现方式懒汉实现方式的特点 什么是单例模式 单例模式是一个设计模式&#xff0c;其目的是确保一个类只有一个实例&#xff0c;并提供一个全局的访问点来访问该实例。单例模式常用于需要控制资源数量的场景&#x…

C++:类的定义和实例化

目录 一、类的定义 1、类的定义格式 2、访问限定符 3、类域 二、实例化 1、实例化的概念 2、对象大小 一、类的定义 1、类的定义格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面分号不能省略。类体中内容…

@TableName(value=““)

Spring中Service对应的实体Entity类上不写TableName(value"")的注解&#xff0c;怎样对应到数据表&#xff1f; 在使用 MyBatis-Plus 时&#xff0c;如果实体类没有使用 TableName(value"") 注解来指定数据库表名&#xff0c;MyBatis-Plus 会根据默认的命…

log4js node日志插件

最近不是特别忙在用express搭建后台项目&#xff0c;在开发过程中遇到了需要输入日志的问 本来想直接用node自带的console来实现&#xff0c;后来发现console输出的日志达不到自己希望的 日志格式&#xff0c;后来各种百度发现了log4js插件&#xff0c;本文来记录log4js插件使用…

STM32智能工业自动化监控系统教程

目录 引言环境准备智能工业自动化监控系统基础代码实现&#xff1a;实现智能工业自动化监控系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;工业自动化与管理问题解决方案与优化收尾与总结 1. 引言 智能…

基于zynq的视频采集与hdmi显示(未完)

文章目录 一、项目整体框架一、传感器配置与驱动二、IMX222 1080P 模式图像解析(bayer 2 rgb 模块)2.1 解析有效像素(gen_sync)2.1.1同步字详细介绍&#xff1a; 2.2 bayer 2 rgb 一、项目整体框架 一、传感器配置与驱动 camera信息&#xff1a;索尼IMX222摄像头 SPI&#xf…

脚本练习-每5分钟执行一次获取当前服务器的基本情况

设计一个shell程序&#xff0c;每5分钟执行一次获取当前服务器的基本情况&#xff08;内存使用率&#xff0c;CPU负载&#xff0c;I/O&#xff0c;磁盘使用率&#xff09;&#xff0c;保存到120.20.20.20数据库上数据库帐号aaa密码bbb库名test表名host 创建一个名为server_stat…

Android10.0 锁屏分析-KeyguardPatternView图案锁分析

首先一起看看下面这张图&#xff1a; 通过前面锁屏加载流程可以知道在KeyguardSecurityContainer中使用getSecurityView()根据不同的securityMode inflate出来&#xff0c;并添加到界面上的。 我们知道&#xff0c;Pattern锁所使用的layout是 R.layout.keyguard_pattern_view&a…

【内网穿透】如何本地搭建Whisper语音识别模型并配置公网地址

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

用C语言写的一个扫雷小游戏

头文件 调用头文件和声明函数 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <time.h> #include <stdlib.h>#define ROW 9 #define COL 9#define ROWS ROW2 #define COLS COL2#define EASY_CONT 10//声明函数 //初始化棋盘函数 void InitB…

【机器学习】Grid Search: 一种系统性的超参数优化方法

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Grid Search: 一种系统性的超参数优化方法引言什么是Grid Search&#xff1f;Gr…

Spring Boot(概要 入门 Spring Boot 核心配置 YAML JSR303数据校验 )

目录 一、Spring Boot概要 1. SpringBoot优点 2. SpringBoot缺点 二、Spring Boot入门开发 1. 第一个SpringBoot项目 项目创建方式一&#xff1a;使用 IDEA 直接创建项目 项目创建方式二&#xff1a;使用Spring Initializr 的 Web页面创建项目 &#xff08;了解&#x…

Jenkins 安装、部署与配置

引言 在软件开发领域&#xff0c;持续集成&#xff08;CI&#xff09;和持续部署&#xff08;CD&#xff09;是提高代码质量和开发效率的关键实践。Jenkins 是一款开源的持续集成/持续部署服务器&#xff0c;以其灵活性和丰富的插件生态系统而闻名。本文将详细介绍 Jenkins 的…

探索 Flask:从入门到精通的完整学习指南

Flask 是当今最流行的 Python Web 框架之一&#xff0c;其简洁、灵活的设计使得开发者能够快速构建强大的 Web 应用。无论你是刚开始学习编程&#xff0c;还是想要深入了解 Web 开发技术&#xff0c;Flask 都是一个理想的起点。本文将带你逐步深入&#xff0c;探索 Flask 的核心…

Java学习高级四

JDK8开始&#xff0c;接口新增了三种形式的方法 接口的多继承 内部类 成员内部类 静态内部类 局部内部类 匿名内部类 import javax.swing.*; import java.awt.event.ActionEvent;public class Test {public static void main(String[] args) {// 扩展 内部类在开发中的真实使用…

深度学习LSTM之预测光伏发电

代码一&#xff1a;训练LSTM模型 代码逐段分析 import numpy as np import pandas as pd import tensorflow.keras as tk from tensorflow.keras import layers首先&#xff0c;导入了必要的库&#xff1a;numpy用于数值计算&#xff0c;pandas用于数据处理&#xff0c;tenso…

Golang 后端面经

文章目录 一、Golanggolang GMP模型Golang中make和new的区别Golang内存逃逸&#xff0c;情况go内存对齐原则map的key值可以是函数、map和切片吗&#xff1f;channel类型可以比较吗容量为1的channel在什么情况下会堵塞&#xff08;除了常见的&#xff09;多线程同时读写map中不同…

搜维尔科技:我们用xsens完成了一系列高难度的运动项目并且捕获动作

我们用xsens完成了一系列高难度的运动项目并且捕获动作 搜维尔科技&#xff1a;我们用xsens完成了一系列高难度的运动项目并且捕获动作