IDW inverse distance weighted average 介绍
反距离加权是一种插值方法
- 目的: 给定一组具有关联值(例如,特定位置的海拔测量值)的已知数据点,IDW 基于附近已知点的值来估计未知位置的值。
- 核心原理: 假设已知点对未知点的影响随着它们之间距离的增加而减小。距离待估计位置更近的点比较远的点具有更高的权重(影响力)。即影响力随着距离成反比
其中:
- x: 我们想要估计值(或特征向量)的查询点。
- xi: 第 i 个已知的邻近数据点。
- fi: 已知点 xi 处的已知值(或特征向量)。
- k: 用于插值的最近邻居的数量。
- wi(x): 分配给已知点 xi 的权重,这取决于到 x 的距离。
权重 wi(x) 通常计算为距离 d(x,xi) 的倒数的 p 次幂:
wi(x)=d(x,xi)p1
- d(x,xi): 查询点 x 和已知点 xi 之间的距离(通常是欧氏距离)。
- p: 一个正实数,称为幂参数或指数。该参数控制权重随距离减小的速度。更高的
p
值会显著增加最近点的影响力,导致插值结果不那么平滑。p
的常用值为 2。
IDW代码
import numpy as np
import matplotlib.pyplot as plt
def idw(points, values, xi, yi, power=2):
"""
反距离加权插值函数
:param points: 已知点的坐标,形状为 (n, 2)
:param values: 已知点的值,形状为 (n,)
:param xi: 目标点的 x 坐标
:param yi: 目标点的 y 坐标
:param power: 权重的幂
:return: 插值结果
"""
# 计算已知点到目标点的距离
distances = np.sqrt((points[:, 0] - xi) ** 2 + (points[:, 1] - yi) ** 2)
# 避免除以0的情况
distances[distances == 0] = 1e-10 # 小值替代
# 计算权重
weights = 1 / distances**power
# 计算插值结果
interpolated_value = np.sum(weights * values) / np.sum(weights)
return interpolated_value
# 示例使用
if __name__ == "__main__":
# 已知点(x, y)
points = np.array([[0, 0], [1, 1], [1, 0], [0, 1]])
values = np.array([1, 2, 3, 4]) # 对应的值
# 目标点
xi, yi = 0.5, 0.5
# 计算插值
result = idw(points, values, xi, yi)
print(f"插值结果: {result}")
# 可视化已知点和插值点
plt.scatter(points[:, 0], points[:, 1], color='blue', label='已知点')
plt.scatter(xi, yi, color='red', label='目标点', marker='x')
plt.title('IDW 插值示例')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid()
plt.show()
为什么Pointnet++中的semantic segmention部分使用IDW?
- 任务是语义分割: 想象一下给一张照片里的每个像素都涂上颜色,表示这个像素属于什么物体(比如“猫”、“狗”、“背景”)。点云语义分割类似,目标是给原始输入的每一个点都分配一个类别标签(比如“椅子”、“桌子”、“地板”)。最终我们需要对所有点都有预测结果。
- 网络结构是分层的: 像 PointNet++ 这样的网络,为了学习更高级、更抽象的特征(比如识别出一个“椅子”的整体结构而不仅仅是几个点),它会逐层减少点的数量(下采样),同时增加每个点所包含的特征信息的维度(变得更“懂”这个点代表什么)。这就好比看一张图片,先看整体轮廓,再看局部细节,但最终的理解是结合了多层信息的。
- 问题出现: 网络在较深的层学到了很好的、能区分“椅子”和“桌子”的特征,但这些特征是附着在少数(下采样后) 点上的。可我们的任务要求对所有原始点进行分类。
总结:下采样后的点太少,语义分割需要对所有点贴标签,所以需要IDW这种插值法去找出最适合的点充当一个上采样的作用