farthest point sampling - FPS - 最远点采样详解 - 附代码实现

目录

最远点采样的基本原理

FPS具体实施细节

最远点采样的特点

应用场景

有两个问题:

FPS相比于随机采样能够更好的覆盖点云集主要有以下原因:

总结

代码实现


最远点采样(Farthest Point Sampling, FPS)是一种在点云处理、计算机图形学和机器学习中常用的采样方法。该方法旨在从一个较大的数据集中选取一个较小的子集,同时尽可能保持原始数据集的结构特征。最远点采样特别适用于需要减少数据点数量以提高处理速度或降低计算复杂度的场景,同时又不希望损失太多原始数据集的关键信息。

最远点采样的基本原理

最远点采样的基本思想是:从数据集中选择一个起始点,然后迭代地选择距离当前已选点集最远的点。这种方法能够确保采样点在空间中相对均匀地分布,从而最大程度地保留数据集的几何结构。

FPS具体实施细节

随着迭代,数组𝑳中元素会越来越小,相当于记录着某个样本中每个点距离所有已出现的采样点的最小距离。

最远点采样的特点

  • 空间覆盖性:最远点采样能够较好地覆盖整个数据集的空间,使采样点分布更加均匀。
  • 效率与准确性的平衡:通过控制采样点的数目,可以在处理速度和保留数据集特征之间找到一个平衡点。
  • 适用性广:最远点采样不依赖于数据的具体特征,可以广泛应用于不同的领域和任务中,如三维点云的下采样、机器学习中的数据预处理等。

应用场景

  • 三维点云处理:在处理大规模三维点云数据时,直接处理可能因数据量过大而导致的计算资源消耗巨大。使用最远点采样可以有效减少点的数量,简化计算过程,同时保留了点云的主要结构特征。
  • 深度学习:在深度学习模型的训练过程中,对输入数据进行下采样可以减少模型的计算负担,加快训练速度。最远点采样因其良好的空间分布性,被用于从大规模数据集中选取有代表性的子集作为网络输入。
  • 数据可视化:在大规模数据集的可视化中,直接渲染可能会因数据量过大而导致性能问题。最远点采样可以用于选取具有代表性的数据点进行可视化,同时尽可能保持整体数据的分布特征。

有两个问题:

1、初始点的选择:

        随机选择一个点(每次结构不同);

        选择距离点云重心的最远点(每次结果相同,一边位于局部极值点,具有刻画能力)。

2、距离度量

        欧氏距离:主要对于点云,在3D空间中均匀采样;

        测地距离:主要对于三角网络,在三角网格面上进行均匀采样。

FPS相比于随机采样能够更好的覆盖点云集主要有以下原因:

1、最大化最小距离:FPS每次选择当前未被选择点中距离已选点最远的点作为新的采样点,确保了新添加的点能够尽可能远离已有的采样点。(这样能使采样点均匀且广泛地分布在整个数据集中,从而最大化地覆盖整个点云集)

2、避免局部过度采样:随机采样可能导致某些区域被过度采样(特别是在采样不均匀的情况下)。相比之下,FPS因每次只寻找最远点,所以他能更有效地探索那些被较少采样的区域。

3、保留数据结构:在点云和复杂几何形状的处理中,FPS能够较好地保留数据的边缘和形状,这对于后续的数据处理和分析非常有帮助。

4、FPS不依赖先验数据,因此适应性更强。

总结

FPS是一种在点云、图像处理或其他数据集中用于抽样的算法。目的是从一个大的数据集中选出一组代表性强的点,这些点彼此之间的最小距离尽可能大

适合减少数据量,同时尽可能的保留原始数据集中的结构和特征。

最远点采样以其简单高效、适用性广的特点,在数据处理和机器学习等多个领域发挥着重要作用。通过合理选择采样点数目,最远点采样既可以保证数据处理的效率,又能在较大程度上保留数据的重要特征,是处理大规模数据集的有效工具之一。

代码实现

def farthest_point_sample(xyz, npoint):
    """
    Input:
        xyz: pointcloud data, [B, N, C]
        npoint: number of samples
    Return:
        centroids: sampled pointcloud index, [B, npoint]
    """
    device = xyz.device
    B, N, C = xyz.shape
    centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)
    distance = torch.ones(B, N).to(device) * 1e10
    farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)
    batch_indices = torch.arange(B, dtype=torch.long).to(device)
    for i in range(npoint):
	# 更新第i个最远点
        centroids[:, i] = farthest
        # 取出这个最远点的xyz坐标
        centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
        # 计算点集中的所有点到这个最远点的欧式距离
        dist = torch.sum((xyz - centroid) ** 2, -1)
        # 更新distances,记录样本中每个点距离所有已出现的采样点的最小距离
        mask = dist < distance
        distance[mask] = dist[mask]
        # 从更新后的distances矩阵中找出距离最远的点,作为最远点用于下一轮迭代
        farthest = torch.max(distance, -1)[1]
    return centroids

参考内容:

【3D计算机视觉】PointNet++的pytorch实现代码阅读_pointnet++ pytorch-CSDN博客

PointNet++详解与代码-CSDN博客

当然可以!下面是一个使用Farthest Point Sampling (FPS)算法找出文件中距离最远的3张图像,并返回图像名的Python代码示例: ```python import os import numpy as np from PIL import Image def compute_distance(image1, image2): # 计算两张图像的距离,可以使用任意方法 # 这里以欧氏距离为例 return np.linalg.norm(image1 - image2) def farthest_point_sampling(images_dir, num_samples=3): # 获取目录下所有图像文件名 image_files = [file for file in os.listdir(images_dir) if file.endswith('.jpg') or file.endswith('.png')] # 随机选择第一个样本 sample_indices = [np.random.randint(len(image_files))] for _ in range(num_samples-1): max_distance = float('-inf') farthest_index = None # 遍历所有图像文件 for i, image_file in enumerate(image_files): if i not in sample_indices: # 加载图像并转换为灰度图 image_path = os.path.join(images_dir, image_file) image = np.array(Image.open(image_path).convert('L')) # 计算当前图像与已选择样本的距离之和 total_distance = 0 for index in sample_indices: sample_path = os.path.join(images_dir, image_files[index]) sample_image = np.array(Image.open(sample_path).convert('L')) total_distance += compute_distance(image, sample_image) # 更新最远距离和索引 if total_distance > max_distance: max_distance = total_distance farthest_index = i # 将最远的图像索引添加到样本列表中 sample_indices.append(farthest_index) # 返回最远的图像文件名 return [image_files[index] for index in sample_indices] # 示例使用 images_directory = 'path/to/images' farthest_images = farthest_point_sampling(images_directory, num_samples=3) print(farthest_images) ``` 你需要将 `images_directory` 替换为包含图像文件的实际路径。此代码将在指定目录中找到距离最远的3张图像,并返回它们的文件名。请确保在运行代码之前安装必要的依赖项(numpy、PIL)。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨晨丶

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值