【发布时间】:2009-12-14 14:10:52
【问题描述】:
我在 2D 图像中有一组随机选择的像素 K。对于图像中的每个其他像素,我需要找出 K 集中的哪个像素最接近它(使用标准的 sqrt(dx^2 + dy^2) 距离度量)。我知道每个像素可能有多个解决方案。显然,它可以通过对集合中的每个像素的蛮力来完成,但我宁愿避免这样做,因为它效率不高。还有什么好的建议吗?
干杯。
【问题讨论】:
我在 2D 图像中有一组随机选择的像素 K。对于图像中的每个其他像素,我需要找出 K 集中的哪个像素最接近它(使用标准的 sqrt(dx^2 + dy^2) 距离度量)。我知道每个像素可能有多个解决方案。显然,它可以通过对集合中的每个像素的蛮力来完成,但我宁愿避免这样做,因为它效率不高。还有什么好的建议吗?
干杯。
【问题讨论】:
别忘了你不需要考虑平方根。
如果您只想找到最近的(而不是实际距离),只需使用dx^2 + dy^2,它会为您提供与每个项目的距离平方,这同样有用。
如果您没有将这个像素列表包装起来的数据结构,您只需针对它们进行测试。
如果您有一定的灵活性,有很多好方法可以减少工作量。创建Quadtree,或保留像素的排序列表(按 x 排序并按 y 排序)以更快地缩小搜索范围。
【讨论】:
sqrt。
我将不得不同意 jk 和 Ewan 制作 Voronoi Diagram。这会将空间划分为多边形。 K 中的每个点都会有一个多边形来描述最接近它的所有点。 现在,当您查询某个点时,您需要找到它位于哪个多边形中。这个问题称为Point Location,可以通过构造Trapezoidal Map 来解决。
jk 已经链接到使用 Fortune's algorithm 创建 Voronoi Diagram,这需要 O(n log n) 计算步骤并花费 O(n) 空间。
This website 教你如何制作梯形图以及如何查询。您还可以在那里找到一些界限:
预期创建时间:O(n log n)
预期空间复杂度:O(n)
但最重要的是,预期的查询时间:O(log n)。这(理论上)比 kD-tree 的 O(√n) 更好。
我的来源(除了上面的链接)是:Computational Geometry: algorithms and applications,第六章和第七章。
您将在此处找到有关这两种数据结构的详细信息(包括详细证明)。 Google 图书版本只有您需要的一部分,但其他链接应该足以满足您的目的。如果您对这类事情感兴趣,就买这本书(这是一本好书)。
【讨论】:
将这些点放在 KD 树中,之后可以非常快地找到最近的邻居。有关详细信息,请参阅维基百科上的 this 文章。
【讨论】:
Voronoi Diagrams 的构造是Computational Geometry 的一个分支。 Delaunay Triangulations 的构造涉及类似的考虑。您可以调整以下Delaunay algorithms 之一以满足您的需求。
【讨论】:
这称为最近邻搜索。 Donald Knuth 称之为邮局问题。
有许多解决方案:线性搜索、局部敏感散列、向量近似文件和空间分区。
谷歌搜索应该会有所帮助。
【讨论】:
您要做的是构造一个voronoi diagram,这可以使用plane sweep 在O(n log n) 中完成
【讨论】:
另一个提示:距离总是大于等于每个坐标差,并且总是小于等于它们的和,即
d >= dx, d >= dy, d <= dx + dy.
这可能会帮助您更有效地进行排序。
【讨论】:
根据该图形填充像素的密集程度,您最好从原始像素向外搜索。
我为图形终端仿真编写了类似的程序。我最终做的是编写一个从中心点长出来的方形螺旋形状的搜索模式,我让它一直增长直到它碰到什么东西。即使在旧 CPU 上,这也足够快。
【讨论】: