首页 > 其他分享 >3d激光雷达开发(ransac的思想)

3d激光雷达开发(ransac的思想)

时间:2022-11-23 23:01:26浏览次数:42  
标签:ransac random RANDOM best total inlier 3d 激光雷达 SIZE


        前面我们写了平面分割、圆柱分割这两篇文章。细心的同学可能发现,这里面都提到了ransac,那什么是ransac呢?

        所谓ransac,全称是random sample consensus,也就是随机采样一致性。名字听上去有点拗口,不妨举个例子来解释。假设一堆点云数据,我们怎么从中找到平面呢?一个简单的方法就是猜?随机找到几个点,算出一个平面,然后计算每个点距离这个平面的距离。继续撒点,如果发现新的点比原来的好,也就是其他点距离平面距离更小,那么更新老的点;否则继续寻找。这个里面,其实做了两个假设,一个假设是我们撒的点正好就在平面上,一个假设是只要样本多,总能找到合适的点。

        网上有一些说明这个原理的文章,部分还提供了代码,比如这一篇,https://zhuanlan.zhihu.com/p/62238520,读起来很是不错。

1、原来的代码有几处bug,修复了一下,

        1.1 i和iters的比较修改为while i < iters:

        1.2 添加i  += 1

        1.3 修正sigma=3,主要是为了提高运行速度,不用等太久

        1.4 添加try-except,防止出现除0异常

        1.5 添加UTF-8,不然中文过不了

2、修改后的代码如下所示,

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import random
import math

# 数据量。
SIZE = 50
# 产生数据。np.linspace 返回一个一维数组,SIZE指定数组长度。
# 数组最小值是0,最大值是10。所有元素间隔相等。
X = np.linspace(0, 10, SIZE)
Y = 3 * X + 10

fig = plt.figure()
# 画图区域分成1行1列。选择第一块区域。
ax1 = fig.add_subplot(1,1, 1)
# 标题
ax1.set_title("RANSAC")


# 让散点图的数据更加随机并且添加一些噪声。
random_x = []
random_y = []
# 添加直线随机噪声
for i in range(SIZE):
random_x.append(X[i] + random.uniform(-0.5, 0.5))
random_y.append(Y[i] + random.uniform(-0.5, 0.5))
# 添加随机噪声
for i in range(SIZE):
random_x.append(random.uniform(0,10))
random_y.append(random.uniform(10,40))
RANDOM_X = np.array(random_x) # 散点图的横轴。
RANDOM_Y = np.array(random_y) # 散点图的纵轴。

# 画散点图。
ax1.scatter(RANDOM_X, RANDOM_Y)
# 横轴名称。
ax1.set_xlabel("x")
# 纵轴名称。
ax1.set_ylabel("y")

# 使用RANSAC算法估算模型
# 迭代最大次数,每次得到更好的估计会优化iters的数值
iters = 100000
# 数据和模型之间可接受的差值
sigma = 3
# 最好模型的参数估计和内点数目
best_a = 0
best_b = 0
pretotal = 0
# 希望的得到正确模型的概率
P = 0.99
i = 0
while i < iters:

# i += 1
i += 1

# 随机在数据中红选出两个点去求解模型
sample_index = random.sample(range(SIZE * 2),2)
x_1 = RANDOM_X[sample_index[0]]
x_2 = RANDOM_X[sample_index[1]]
y_1 = RANDOM_Y[sample_index[0]]
y_2 = RANDOM_Y[sample_index[1]]

# y = ax + b 求解出a,b
a = (y_2 - y_1) / (x_2 - x_1)
b = y_1 - a * x_1

# 算出内点数目
total_inlier = 0
for index in range(SIZE * 2):
y_estimate = a * RANDOM_X[index] + b
if abs(y_estimate - RANDOM_Y[index]) < sigma:
total_inlier = total_inlier + 1

# 判断当前的模型是否比之前估算的模型好
if total_inlier > pretotal:
try:
iters = math.log(1 - P) / math.log(1 - pow(total_inlier / (SIZE * 2), 2))
except ZeroDivisionError:
pass

pretotal = total_inlier
best_a = a
best_b = b

# 判断是否当前模型已经符合超过一半的点
if total_inlier > SIZE:
break

# 用我们得到的最佳估计画图
Y = best_a * RANDOM_X + best_b

# 直线图
ax1.plot(RANDOM_X, Y)
text = "best_a = " + str(best_a) + "\nbest_b = " + str(best_b)
plt.text(5,10, text,
fontdict={'size': 8, 'color': 'r'})
plt.show()

3、实际效果

3d激光雷达开发(ransac的思想)_3d

        代码没有修改之前,可能会出现除0错误,而且执行时间很长,有差不多10几秒钟,修改后可以短时间快速出结果。

4、最有意思的更新

# 判断当前的模型是否比之前估算的模型好
if total_inlier > pretotal:
try:
iters = math.log(1 - P) / math.log(1 - pow(total_inlier / (SIZE * 2), 2))
except ZeroDivisionError:
pass

pretotal = total_inlier
best_a = a
best_b = b

        对iters的重新计算是最有意思的,实际效果也许有限。注意虽然SIZE是50,但是实际random_x、random_y的大小是100,所以这里乘以2。此外后面一个2,代表每次只需取两个点即可,所以N=2。其他部分和k=log(1-P)/log(1-t的N次方)这个公式是完全匹配的。

标签:ransac,random,RANDOM,best,total,inlier,3d,激光雷达,SIZE
From: https://blog.51cto.com/feixiaoxing/5881892

相关文章

  • 3d激光雷达开发(项目练习)
            网上关于pcl的教程很多,大部分都是翻译过来的。但是怎么把pcl这些教程串在一起,做一个简单的项目,这方面的资料不多。今天,正好看到一个范例项目,很有代表性,值得......
  • 3d激光雷达开发(平面分割)
        平面分割是点云数据经常需要处理的一个功能。在很多场景下面,平面数据都是没有用的。这个时候需要考虑的,就是怎么把平面数据从点云当中分割出去。鉴于此,pcl库给......
  • 3d激光雷达开发(圆柱分割)
        和平面分割一样,pcl也支持圆柱分割。使用的方法和平面分割也差不多,都是基于ransac的基本原理。在pcl官方库当中,也给出了参考代码,注意关联的pcd文件,https://pcl.r......
  • 3d激光雷达开发(ndt匹配)
        除了icp匹配之外,ndt匹配也是使用比较多的一种方法。相比较icp而言,ndt匹配花的时间要少一些。此外,ndt匹配还需要输入估计的yaw、pitch、roll、x、y、z,这个可以根......
  • 3d激光雷达开发(icp匹配)
        所谓匹配,其实就是看两个点云数据里面,哪些关键点是一样的。这样就可以把一个点云移动到另外合适的位置,组成一个新的点云。一般来说,单个机器人上面,3d激光扫描到的......
  • Transaction rolled back because it has been marked as rollback-only原因及解决办
    异常:Transactionrolledbackbecauseithasbeenmarkedasrollback-only原因:已经标记为rollback-only,但是后面的程序执行后又commit事务,抛出此异常。虽然都回滚,不影响......
  • ASW3642pin√pin替代TS3DV642无需更改电路
    TS3DV642是一种12通道1:2或2:1双向多路替代器/多路解复用器。TS3DV642接入2.6V至4.5V的电源供电,适用于电池供电。电阻(RON)最小和I/O电容较小,能够实现典型值高达7.5GHz的带宽......
  • 3DMAX2018安装
    1.下载3DMAX2018安装包并解压2.打开解压后的文件点击Setup选择语言和安装位置点击下一步安装完成后点击enteraserialnumber输入序列号066-66666666,密钥128J1后点......
  • 大咖说·先临三维|技术入云塑造3D视觉行业新模式
    高精度3D视觉技术主要的工作原理是什么?它的开发难度在哪里?数字化技术对其有何助力?本期大咖说,看先临三维副总裁兼研究院副院长江腾飞如何分享。嘉宾介绍江腾飞:先......
  • Matplotlib数据可视化——3D视图
    """绘制三维图形"""importnumpyasnpimportmatplotlib.pyplotaspltfrommpl_toolkits.mplot3dimportAxes3Dfig=plt.figure()ax=Axes3D(fig)X=np.ara......