【FPS】最远点采样Python实现

文章目录

      • 1.FPS算法实现步骤
      • 2.Python实现
      • 3.结果

\quad 在 PointNet++ 中用到了FPS(Farthest Point Sampling) 最远点采样法,该方法比随机采样的优势在于它可以尽可能的覆盖空间中的所有点。

1.FPS算法实现步骤

\quad 假设点集中共有 N 0 N_{0} N0个点,需要采样 N 1 N_{1} N1个点

step1 \textbf{step1} step1

\quad 在点集 S 0 S_{0} S0中随机选一个点 p 0 p_{0} p0,并且计算点 p 0 p_{0} p0 S 0 S_{0} S0中剩下所有点的距离,得到距离最大的点 p 1 p_{1} p1。将 p 0 , p 1 p_{0},p_{1} p0,p1 S 0 S_{0} S0中移除,加入点集 S 1 S_{1} S1中,此时 S 1 = { p 0 , p 1 } S_{1} = \left\{ p_{0},p_{1}\right\} S1={p0,p1}

step2 \textbf{step2} step2

\quad 首先计算 S 1 S_{1} S1中的每个点与 S 0 S_{0} S0中的每个点的距离,取最小值,如图: m i n { l 0 , l 1 } min \left\{l_{0},l_{1}\right\} min{l0,l1}

【FPS】最远点采样Python实现_第1张图片
\quad 计算完 S 1 S_{1} S1中的每个点到 S 0 S_{0} S0中的每个点的距离,并取最小值之后,再将所有值取最大值:
m a x { m i n { l i 0 , l i 1 } } , i = 1 , 2... N − 2 max\left\{ min\left\{l_{i0},l_{i1}\right\} \right\},i = 1,2...N-2 max{min{li0,li1}},i=1,2...N2

\quad 之后将该点 p 2 p_{2} p2,从 S 0 S_{0} S0中移除,加入 S 1 S_{1} S1,此时 S 1 = { p 0 , p 1 , p 2 } S_{1} = \left\{ p_{0},p_{1},p_{2}\right\} S1={p0,p1p2} S 1 S_{1} S1中已经有3个点了。

step3 \textbf{step3} step3

\quad 循环执行 step2 \textbf{step2} step2,直到 S 1 S_{1} S1中的点为 N 1 N_{1} N1个即可。

2.Python实现

import random
import math
import matplotlib.pyplot as plt

M = 50 # 所有的点数量
N = 10 # fps采样点数量
x = []
y = []
xy = []

# 生成数据
random.seed(0)
for _ in range(M):
    px = round(random.uniform(1, 10), 2)  # 生成随机数,浮点类型 控制2位精度
    py = round(random.uniform(1, 10), 2)
    x.append(px)
    y.append(py)
    xy.append((px, py))

# 显示生成的点
plt.figure(figsize=(10, 4))
plt.subplot(121)
plt.title('init_points')
plt.scatter(x, y, marker='o', c='', edgecolors='b', s=200)

select = []
rest = [num for num in range(0, M)]

max_dist = -99999
farthest_point = 99999

# step 1 随机选择一个点
random.seed(1)
ind = random.randint(0, M - 1)
select.append(ind)
rest.remove(ind)
# print('select', select)
# print('rest', rest)

# 计算距离,找到距离第一个点最远的点
for i in range(len(xy)):
    if i != ind:
        length = math.sqrt(math.pow(abs(xy[ind][0] - xy[i][0]), 2) + math.pow(abs(xy[ind][1] - xy[i][1]), 2))
        if length > max_dist:
            max_dist = length
            farthest_point = i
select.append(farthest_point)
rest.remove(farthest_point)
print('select', select)
print('rest', rest)

# print(dist)
# print(max_dist)
# print(farthest_point)

# step 2 先min,再max
print('----after----')
while len(select) < N:
    min_length = []
    max_dist = -99999

    for i in range(len(rest)):
        min_dist = 99999

        for j in range(len(select)):
            length = math.sqrt(
                math.pow(abs(xy[rest[i]][0] - xy[select[j]][0]), 2) + math.pow(abs(xy[rest[i]][1] - xy[select[j]][1]),
                                                                               2))
            if length < min_dist:  # 先取最小
                min_dist = length

        min_length.append((rest[i], min_dist))

        if list(min_length[i])[1] > max_dist:  # 再取最大
            max_dist = list(min_length[i])[1]
            farthest_point = list(min_length[i])[0]

    # print(min_length)
    # print(max_dist)
    # print(farthest_point)
    # print('------------------------')
    select.append(farthest_point)
    rest.remove(farthest_point)

print('select', select)
print('rest', rest)

# fps点
new_x = []
new_y = []
for i in range(len(select)):
    new_x.append(xy[select[i]][0])
    new_y.append(xy[select[i]][1])

plt.subplot(122)
plt.title('select_points')
plt.scatter(x, y, marker='o', c='', edgecolors='b', s=200)  # edgecolors是控制圆圈的边缘颜色,c是控制圆心的颜色,c=''就是空心
plt.scatter(new_x, new_y, marker='o', c='red', edgecolors='r', s=200)
plt.text(new_x[0] + 0.1, new_y[0] + 0.1, "first_point", size=10, color="m")
plt.text(new_x[1] + 0.1, new_y[1] + 0.1, "second_point", size=10, color="m")
# plt.savefig("FPS.png")
plt.show()

3.结果

【FPS】最远点采样Python实现_第2张图片

你可能感兴趣的:(Python,目标检测)