点云算法-提取kitti路面点云

news2024/12/23 18:47:06

目录

一、ransac原理

二、ransac 地面分割原理

三、ransac常见应用

四、代码

五、截图

六、总结


一、ransac原理

RANSAC是“random sample consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估计数学模型的参数。

它是一种不确定的算法,它有一定的概率得出一个合理的结果;为了提高概率必须提高迭代次数。

划重点:

1、定义一个要估计的模型

2、迭代求解模型参数

3、迭代的条件通过概率进行判断是否合理

RANSAC的基本假设是: 
(1)数据由“局内点”组成,例如:数据的分布可以用一些模型参数来解释; 
(2)“局外点”是不能适应该模型的数据; 
(3)除此之外的数据属于噪声。 
局外点产生的原因有:噪声的极值;错误的测量方法;对数据的错误假设。 
RANSAC也做了以下假设:给定一组(通常很小的)局内点,存在一个可以估计模型参数的过程;而该模型能够解释或者适用于局内点。

二、ransac 地面分割原理

根据刚总结的:

1、定义一个要估计的模型

2、迭代求解模型参数

3、迭代的条件通过概率进行判断是否合理

对应进行算法设计:

1、定义平面表达方程为 aX + bY + cZ +D= 0,通过道理,如果要提取的数据能够通过模型来描述,如直线、球、圆柱、平面等的拟合与分割,都可以考虑使用ransac思路

2、迭代过程

  • 求解法向量用于求解平面方程abcd参数
  • 通过计算距离,判断是否是比较好的迭代效果,如果是,更新参数

    计算距离:distance = abs(pointn_1.dot(N)) / np.linalg.norm(N)  # 求距离

  • 计算就算最佳迭代次数

 

iters = math.log(1 - P) / math.log(1 - pow(total_inlier / n, 3))

3、概率判断条件

当内点个数满足设置的要求

 # 判断是否当前模型已经符合超过 inline_ratio
        if total_inlier > n * (1 - outline_ratio):
            break

三、代码


import numpy as np
import open3d as o3d
import struct
import matplotlib.pyplot as plt
from pandas import DataFrame
from pyntcloud import PyntCloud
import math
import random
#import Spectral as sp
from collections import defaultdict


# 功能:从kitti的.bin格式点云文件中读取点云
# 输入:
#     path: 文件路径
# 输出:
#     点云数组
def read_velodyne_bin(path):
    '''
    :param path:
    :return: homography matrix of the point cloud, N*3
    '''
    pc_list = []
    with open(path, 'rb') as f:
        content = f.read()
        pc_iter = struct.iter_unpack('ffff', content)
        for idx, point in enumerate(pc_iter):
            pc_list.append([point[0], point[1], point[2]])
    return np.asarray(pc_list, dtype=np.float32)


# 功能:从点云文件中滤除地面点
# 输入:
#     data: 一帧完整点云
# 输出:
#     segmengted_cloud: 删除地面点之后的点云
def ground_segmentation(data):
    # 作业1
    # 屏蔽开始
    # 初始化数据
    idx_segmented = []
    segmented_cloud = []
    iters = 100  # 最大迭代次数  000002.bin:10
    sigma = 0.4  # 数据和模型之间可接受的最大差值   000002.bin:0.5   000001.bin: 0.2  000000.bin: 0.15  002979.bin:0.15  004443.bin:0.4
    ##最好模型的参数估计和内点数目,平面表达方程为   aX + bY + cZ +D= 0
    best_a = 0
    best_b = 0
    best_c = 0
    best_d = 0
    pretotal = 0  # 上一次inline的点数
    # 希望的到正确模型的概率
    P = 0.99
    n = len(data)  # 点的数目
    outline_ratio = 0.6  # e :outline_ratio   000002.bin:0.6    000001.bin: 0.5  000000.bin: 0.6   002979.bin:0.6
    for i in range(iters):
        ground_cloud = []
        idx_ground = []
        # step1 选择可以估计出模型的最小数据集,对于平面拟合来说,就是三个点
        sample_index = random.sample(range(n), 3)  # 重数据集中随机选取3个点
        point1 = data[sample_index[0]]
        point2 = data[sample_index[1]]
        point3 = data[sample_index[2]]
        # step2 求解模型
        ##先求解法向量
        point1_2 = (point1 - point2)  # 向量 poin1 -> point2
        point1_3 = (point1 - point3)  # 向量 poin1 -> point3
        N = np.cross(point1_3, point1_2)  # 向量叉乘求解 平面法向量
        ##slove model 求解模型的a,b,c,d
        a = N[0]
        b = N[1]
        c = N[2]
        d = -N.dot(point1)
        # step3 将所有数据带入模型,计算出“内点”的数目;(累加在一定误差范围内的适合当前迭代推出模型的数据)
        total_inlier = 0
        pointn_1 = (data - point1)  # sample(三点)外的点 与 sample内的三点其中一点 所构成的向量
        distance = abs(pointn_1.dot(N)) / np.linalg.norm(N)  # 求距离
        ##使用距离判断inline
        idx_ground = (distance <= sigma)
        total_inlier = np.sum(idx_ground == True)  # 统计inline得点数
        ##判断当前的模型是否比之前估算的模型
        if total_inlier > pretotal:  # log(1 - p)
            iters = math.log(1 - P) / math.log(1 - pow(total_inlier / n, 3))  # N = ------------
            pretotal = total_inlier  # log(1-[(1-e)**s])
            # 获取最好得 abcd 模型参数
            best_a = a
            best_b = b
            best_c = c
            best_d = d

        # 判断是否当前模型已经符合超过 inline_ratio
        if total_inlier > n * (1 - outline_ratio):
            break
    print("iters = %f" % iters)
    # 提取分割后得点
    idx_segmented = np.logical_not(idx_ground)
    ground_cloud = data[idx_ground]
    segmented_cloud = data[idx_segmented]
    return ground_cloud, segmented_cloud

    # 屏蔽结束

    # print('origin data points num:', data.shape[0])
    # print('segmented data points num:', segmengted_cloud.shape[0])
    # return segmengted_cloud


def main():
    iteration_num = 1  # 文件数

    # for i in range(iteration_num):
    filename = 'data/000001.bin'  # 数据集路径
    print('clustering pointcloud file:', filename)

    origin_points = read_velodyne_bin(filename)  # 读取数据点
    origin_points_df = DataFrame(origin_points, columns=['x', 'y', 'z'])  # 选取每一列 的 第0个元素到第二个元素   [0,3)
    point_cloud_pynt = PyntCloud(origin_points_df)  # 将points的数据 存到结构体中
    point_cloud_o3d = point_cloud_pynt.to_instance("open3d", mesh=False)  # 实例化
    #
    #o3d.visualization.draw_geometries([point_cloud_o3d])  # 显示原始点云

    # 地面分割
    ground_points, segmented_points = ground_segmentation(data=origin_points)

    ground_points_df = DataFrame(ground_points, columns=['x', 'y', 'z'])  # 选取每一列 的 第0个元素到第二个元素   [0,3)
    point_cloud_pynt_ground = PyntCloud(ground_points_df)  # 将points的数据 存到结构体中
    point_cloud_o3d_ground = point_cloud_pynt_ground.to_instance("open3d", mesh=False)  # 实例化
    point_cloud_o3d_ground.paint_uniform_color([0, 0, 255])
    o3d.visualization.draw_geometries([point_cloud_o3d_ground])  # 显示地面点云


if __name__ == '__main__':
    main()

四、截图

五、总结

ransac模型的拟合的取决于物体的密度分布,在三维场景较为适合,但是ransac具有随机性,所以每次运行的结果不尽相同。

ransac应用广泛,也有使用ransac进行影像处理的。比如下边来之一片论文在摘要:

本文首先介绍 RANSAC 算法的发展、原理及其改进算法。重点介绍其在遥感图像处理中几何校正和辐射校正的应用。在几何校正中一般是得到控制点对后,直接进行矫正模型的拟合,没有考虑异常数据的影响。本文利用 RANSAC 算法,剔除误匹配点后再拟合模型。在利用 RANSA算法迭代得出稳健的模型参数前,首先要选择合适的几何模型,常用的几何模型是基本矩阵和单应矩阵。在遥感图像几何处理部分,本文主要针对几何处理中的图像配准进行实验。图像配准分为基于灰度特征和基于特征点的匹配方法。本文实验中图像配准基于特征点,计算基本矩阵筛选出影响模型参数的误匹配点:实验表明 RANSAC 算法剔除误匹配点后匹配效果明显,校正精度显著提高至1到2个像元误差。
遥感图像辐射校正分为绝对辐射校正和相对辐射校正。本文主要针对相对辐射校正线性回归法应用 RANSAC 算法,在寻找两幅图像重叠区域像素间线性关系中,剔除异常数据点,最大限度的利用支持线性模型的数据点拟合得到两图像的辐亮度线性变换模型参数。本文针对一些辐射校正后颜色平衡效果不好的情况,提出对像素点先聚类再拟合的方法。
最后介绍对 RANSAC算法的一些改进以便提高其运算效率。基于 RANSAC算法原理,主要可以从两方面对其改进:每次迭代样本的选取和模型参数的检验。本文除了介绍预检验模型参数的原理,更主要是根据样本选取提出了更加有效的样本预检验模型,即在原来预检验的基础上增加样本预检验。这样不仅减少检验模型参数的计算量同时也提高了样本选取的效率。

其主要目标,还是用来去掉数据集中的外点,增加数据的精度。

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

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

相关文章

【408篇】C语言笔记-第二十一章(汇编语言)

文章目录第一节&#xff1a;汇编指令格式讲解1. 汇编指令格式2. 生成汇编方法第二节&#xff1a;汇编常用指令讲解1. 相关寄存器2. 常用指令3. 条件码第三节&#xff1a;各种变量赋值汇编实战1. 各种变量赋值汇编实战解析第四节&#xff1a;选择循环汇编实战1. 选择循环汇编实战…

基于ssm+mysql+jsp实现歇后语管理系统

基于ssmmysqljsp实现歇后语管理系统一、系统介绍二、系统展示1.歇后语大全2.歇后语排行榜3.歇后语管理4.用户管理三、其它系统四、获取源码一、系统介绍 本系统实现了 普通用户&#xff1a;歇后语大全、歇后语排行榜、歇后语管理 管理员用户&#xff1a;歇后语大全、歇后语排行…

一键替换Markdown文件的字体样式

功能说明 一键替换MD文件的字体样式&#xff1a;加粗字体—>橙色不加粗 也可以针对其它样式做切换&#xff0c;源码就一个demo类&#xff0c;修改正则匹配相关变量即可&#xff1b; 环境要求&#xff1a; windows jdk1.8 工具下载 百度网盘&#xff1a;提取码: ae16 …

week9

T1【深基18.例3】查找文献 题目描述 小K 喜欢翻看洛谷博客获取知识。每篇文章可能会有若干个&#xff08;也有可能没有&#xff09;参考文献的链接指向别的博客文章。小K 求知欲旺盛&#xff0c;如果他看了某篇文章&#xff0c;那么他一定会去看这篇文章的参考文献&#xff0…

7.1 定义抽象数据类型

文章目录定义改进的Sales_data 类定义成员函数引入this指针引入const成员函数类作用域和成员函数在类的外部定义成员函数定义返回this的函数类的静态成员定义类相关的非成员函数构造函数合成的默认构造函数某些类不能依赖合成的默认构造函数定义构造函数拷贝 赋值和析构某些类不…

11.2、基于Django4的可重用、用户注册和登录系统搭建(优化)

文章目录前端界面设计与优化完善登录界面的视图函数session会话和登出的视图函数将当前代码推送至Gitee添加图片验证码前端界面设计与优化 使用CSS框架 Bootstrap4&#xff0c;Bootstrap将CSS样式和JS都封装好了&#xff0c;可以直接使用。 下面使用的Bootstrap模板来自官方文…

AHB协议(1/2)

AHB协议&#xff08;1/2&#xff09; 以下内容为AMBA5 AHB Protocol Specification协议内容 Charpter 1 Introduction 1.1 关于AHB协议 AMBA AHB是一个支持高性能设计的总线接口。他在组件间&#xff0c;如主端&#xff08;Master&#xff09;&#xff0c;互联结构&#xf…

云原生之使用Docker部署Dailynotes个人笔记管理工具

云原生之使用Docker部署Dailynotes个人笔记管理工具一、Dailynotes介绍二、检查本地docker环境1.检查docker版本2.检查docker状态三、下载Dailynotes镜像四、创建Dailynotes容器1.创建数据目录2.创建Dailynotes容器3.查看Dailynotes容器状态五、访问Dailynotes1.进入Dailynotes…

uniCloud云开发----5、uni-id-pages的使用

uni-id-pages的使用前言1、下载uni-id-pages插件2、查看登录页面3、配置项云端配置config.json前言 在开发过程中&#xff0c;会发现微信小程序的登录方式不断地更新和变化&#xff0c;这样导致我们在开发过程中非常的困难&#xff0c;uni-id-pages直接集成的页面和数据库来实…

67、【链表】leetcode——242. 有效的字母异位词(C++版本)

题目描述 原题链接&#xff1a;242. 有效的字母异位词 一、ASCII码作为Key 因s和t都为小写字母&#xff0c;因此可将s和t中字母用ASCII码数字表示&#xff0c;减去a&#xff0c;映射到0-25当中&#xff0c;作为Hash表映射结构。 首先&#xff0c;查看s和t的长度是否相同&…

09线性相关、基、维数

线性相关、基、维数 知识概要 ​ 从线性相关或线性无关的特征入手,介绍空间的的几个重要概念:基、维数 线性无关与线性相关 (1)背景知识: 谈论的概念都是基于向量组的,而不是基于矩阵。线 性无关,线性相关是向量组内的关系,基也是一个向量组,不要与矩阵概念混淆。 首先…

华为云工程师HCIA——服务器技术基础

服务器的定义 服务器是计算机的一种。他比普通计算机运行熟读更快、负载更高而且价格更高。 服务器是为用户提供服务的计算机&#xff0c;通常分为文件服务器、数据库服务器和应用程序服务器。 服务器特点 可用性可扩展性可管理性易用性可靠性 服务器硬件结构 Huawei2280…

01 大数据概述

01 大数据概述1、大数据&#xff1a; 主要用来解决海量数据的存储和海量数据的分析计算问题。 2、大数据的特点&#xff1a; 大量&#xff08;Volume&#xff09;&#xff1a;一些大企业的数据量已经接近EB量级。高速&#xff08;Velocity&#xff09;: 随着数据量的增大&…

B树的原理及代码实现、B+树和B*树介绍及应用

目录 一.B树介绍 &#xff08;一&#xff09;.B树存在意义 &#xff08;二&#xff09;.B树的规则 二.B树实现原理及代码 &#xff08;一&#xff09;.实现原理 &#xff08;二&#xff09;.代码 三.B树 &#xff08;一&#xff09;.概念 &#xff08;二&#xff09;.应…

Python批量采集某网站高清壁纸,这下不用担心没壁纸换了

前言 咳咳&#xff0c;担心壁纸不够用&#xff1f;想要一天换一张&#xff1f;ok &#xff0c;今天就来搞搞壁纸网站 之前老有很多高质量的网站都不见了&#xff0c;趁着这个还在&#xff0c;赶紧多保存点 话不多说 马上开始 我的表演 代码 导入模块 所有 源码 点击 此处 领…

矩阵快速幂(新手做法)

1.通过一个代码来了解矩阵乘法2.基本快速幂3.那么最后就是矩阵快速幂了4.练习模板&#xff1a;5.进阶运用&#xff0c;蓝桥杯15届省赛c语言组第9题矩阵快速幂的学习流程&#xff1a; 矩阵乘法运算规则&#xff08;线性代数基础&#xff09;快速幂的模板 1.通过一个代码来了解矩…

S32K144—什么是SBC系统基础芯片?

SBC&#xff08;System Basis Chip&#xff09;芯片在汽车电子领域可谓占一席之地了。那么什么是SBC&#xff1f;怎么用&#xff1f;用在哪里&#xff1f;主要特性&#xff1f; 可以简单理解成&#xff1a;SBC是一类拥有特出功能&#xff08;电源、通信、监控诊断、安全&#…

【附源码】基于fpga的自动售货机(使用三段式状态机实现)

目录 1、VL38 自动贩售机1 题目介绍 思路分析 代码实现 仿真文件 2、VL39 自动贩售机2 题目介绍&#xff1a; 题目分析 代码实现 仿真文件 3、状态机基本知识 1、VL38 自动贩售机1 题目介绍 设计一个自动贩售机&#xff0c;输入货币有三种&#xff0c;为0.5/1/2元&…

嵌入式Linux驱动开发笔记(八)

嵌入式Linux驱动开发笔记&#xff08;八&#xff09; 交叉编译工具说明&#xff1a; 正点原子提供两种交叉编译工具链。这两种交叉编译工具链解释如下图。 我们只需要知道上面的第二种通用的交叉编译器去学习【正点原子】 I.MX6U 嵌入式 Linux 驱动开发指南这本教程。第一种…

lscpu查看cpu信息

$ lscpu Architecture: x86_64 # 架构CPU op-mode(s): 32-bit, 64-bitAddress sizes: 45 bits physical, 48 bits virtualByte Order: Little Endian # 字节序 CPU(s): 2 # 逻辑cpu数On-line CPU(s) list: 0,1 Vendo…