三维点云处理05-FPS代码实现

三维点云处理05-FPS代码实现

基础知识点
  • 最远点采样原理解释:
    1.从原始点云中选取一个初始点作为最远点
    2.设定我们希望获得的最远点的数量npoints
    3.进行npoints次循
    4.每次循环中计算原点点云中每个点到距离它最近的最远点的距离
    5.然后从中选出距离最大的点作为下一个最远点
    在这里插入图片描述
  • 上图解释:
    1.首先从原始点云中选择一个点作为初始点
    2.然后计算原始点云中所有点到该初识最远点的距离,获得第二个最远点
    3.然后计算原始点云中所有点到第二个最远点的距离,并与第一个最远点的距离进行比较,使用距离较小的更新距离矩阵(这里是因为FPS算法中每个点都是选择与它最近的最远点计算距离)
    4.然后从距离矩阵中选择距离最远点集合距离最大的作为第三个最远点
    5.以此类推,重复3,4
  • 这里再贴一个大佬的FPS算法总结
    1.输入点云有N个点,从点云中选取一个点P0作为起始点,得到采样点集合S={P0};
    2.计算所有点到P0的距离,构成N为数组L,从中选择最大值对应的点作为P1,更新采样点集合S={P0,P1}
    3.计算所有点到P1的距离,对于每一个点Pi,其到P1的距离如果小于当前L中的L[i],则更新L[i],也就是L[i] = d{Pi,P1},因此,可以看出距离矩阵L中存放的一直是每一个点到采样点集合S的最近距离(也就是每个点都与其最近的最远点计算距离)
    4.选择距离矩阵L中最大值对应的点作为P2,更新采样点集合S={P0,P1,P2}
    5.重复2-4步,一直采样到N个目标采样点为止
初始点如何选择
  • 随机选择一个点,这种选择方式的缺点是每次FPS获得的结果都不同
  • 选择距离点云重心的最远点,每次FPS的结果都相同,一般位于局部极值点,具有刻画能力
距离度量如何选择
  • 欧式距离:主要对于点云,在3D空间均匀采样
  • 测地距离:主要用于三角网格,在三角网格面上均匀采样
FPS代码实现
import torch
from torch.autograd import Variable

def farthest_point_sample(xyz,npoint):
	'''
	输入:
	xyz: B C N
	npoint:最远点采样的样本数
	输出:
	最远点采样的结果: B npoint
	'''
	
	#因为输入数据为B C N,所以首先对第1和第2维度进行转置
	xyz = xyz.transpose(2,1)
	#获得xyz的device
	device = xyz.device
	#获得xyz的维度
	B,N,C = xyz.shape
	#初始化最远点采样点矩阵,可以多个batch一起进行最远点采样
	centroids = torch.zeros(B,npoint,dtype=torch.long).to(device)
	#初始化采样点到所有点的距离矩阵,特别注意,这里其实是使用distance矩阵
	#保存所有点到最远点采样矩阵的最大距离
	distance = torch.ones(B,N).to(device) * 1e10
	#初始化batch_size数组
	batch_indices = torch.arange(B,dtype=torch.long).to(device)
	
	#计算输入点云的重心
	#按照第1维度对输入点云进行求和,得到的是B,1,C
	barycenter = torch.sum((xyz),1)
	#计算重心 B 1 C
	barycenter = barycenter / xyz.shape[1]
	arycenter = barycenter.view(B,1,3)
	
	#计算所有点到重心的距离 B N C
	dist = torch.sum((xyz - barycenter)**2, -1)
	#选择距离重心最远的点作为第一个点 B 1 ,[1]表示返回的是index,[0]表示返回的是值
	farthest = torch.max(dist,1)[1]
	
	for i in range(npoint):
		#centroid[:,i] B,1
		centroids[:,i] = farthest
		#从xyz中取出最远点 B,1,C
		centroid = xyz[batch_indices,farthest,:].view(B,1,3)
		#计算所有点到最远点的距离 B,npoint,C
		dist = torch.sum((xyz - centroid)**2,-1)
		#然后更新所有点到最远点集合的距离矩阵,注意距离矩阵中维持的始终
		#是所有点到最远点集合的最小距离
		mask = dist < distance
		distance[mask] = dist[mask]
		#然后找出距离矩阵中的最大值对应的点对最远点集合进行更新
		farthest = torch.max(distance,-1)[1]
		
	return centroids
		
if __name__ == '__main__':
	#创建点云数据,注意点云数据的维度对应为batch, channel, N
	sim_data = Variable(torch.rand(1,3,8))
	#调用最远点采样函数,获得最远点
	centroid = farthest_point_sample(sim_data, 4)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值