【发布时间】:2015-08-05 09:04:51
【问题描述】:
我有两个相关的 Nx3 数据集(一个是 xyz 点,另一个是这些点的法线向量)。我的第一个数据集中有一个点,现在我想在第二个数据集中找到匹配的行。最好的方法是什么?我在考虑打印行号,但不确定代码到底是什么?
【问题讨论】:
我有两个相关的 Nx3 数据集(一个是 xyz 点,另一个是这些点的法线向量)。我的第一个数据集中有一个点,现在我想在第二个数据集中找到匹配的行。最好的方法是什么?我在考虑打印行号,但不确定代码到底是什么?
【问题讨论】:
假设您在一个数据集中有一个大小为 1 x 3 的点,您可以通过两种可能的方式来执行此操作。
knnsearch
最简单的方法是使用统计工具箱中的knnsearch。
knnsearch 代表 K-Nearest Neighbor 搜索。给定一个输入查询点,knnsearch 会在给定输入查询点的情况下找到与您的数据集最近的k 点。在您的情况下,k=1。此外,距离度量是欧几里得距离,但看看你的点在 3D 笛卡尔空间中的情况,我认为这不是问题。
因此,假设您的xyz 点存储在X 中,查询点(法线向量)在y 中,只需这样做:
IDX = knnsearch(X, y);
以上默认为k=1。如果您希望退回超过 1 分,您可以这样做:
IDX = knnsearch(X, y, 'K', n);
n 是您想要返回的点数,或者是给定查询y 时最接近的点数n。 IDX 包含X 中最接近y 的点的索引。我还想指出,X 的排列方式是,每个 row 都是一个点,每个 column 都是一个变量。
因此,使用IDX 的最近点是:
closest_point = X(IDX,:);
bsxfun
如果您没有统计工具箱,您可以使用bsxfun 轻松实现相同的目标。请记住,我将编写的代码仅用于返回最近的点,或者k=1:
dists = sqrt(sum(bsxfun(@minus, X, y).^2, 2));
[~,IDX] = min(dists);
bsxfun 调用首先确定y 和X 中每个点之间的组件距离。一旦我们这样做了,我们将每个组件平方,将所有组件加在一起,然后取平方根。这基本上找到了y 和X 中所有点的欧几里得距离。这给了我们N 距离,其中N 是数据集中的点总数。然后我们找到与min的最小距离,并确定最近匹配点所在的索引,它对应于y与数据集之间最近的点。
如果您想将其扩展到多个点,您可以按升序对距离进行排序,然后检索距离最小的点数。请记住,较小的欧几里得距离意味着点相似,这就是我们按升序排序的原因。像这样的:
dists = sqrt(sum(bsxfun(@minus, X, y).^2, 2));
[~,ind] = sort(dists);
IDX = ind(1:n);
与我们之前的相比仅提升了一小步。您可以使用sort 并获得sort 的第二个输出来确定最小距离的位置,而不是使用min。然后我们将索引到ind 以获取最接近的n 索引,最后索引到X 以获取我们的实际分数。
您将再次执行相同的操作来检索最接近的实际点:
closest_point = X(IDX,:);
如果您想详细了解 K-Nearest Neighbor 的工作原理,我鼓励您在此处阅读我的帖子:
Finding K-nearest neighbors and its implementation
祝你好运!
【讨论】: