【问题标题】:Check if a point lies inside a rectangle检查一个点是否位于矩形内
【发布时间】:2013-10-08 17:14:07
【问题描述】:

我在 openCV 中做一个项目。然而,语言不是这个问题。

比如说,我有一个矩形数组。我有一个坐标为x和y的点数组。 我的问题是除了使用蛮力技术并用我拥有的每个矩形检查一个点之外,是否有更好、更优雅的解决方案。

我在这个链接看到了一个类似的问题,但不明白解决方案:

Check if an array of points is inside an array of rectangles?

背景信息(适用于了解图像处理的人)

请看一下这个问题:Detecting Markers in a video Sequence 我在更好的时间限制内要求上述内容的原因是因为这个。我认为相同的算法是在每个标记周围制作一个矩形,并在下一帧中搜索矩形内的标记。如果它位于一个矩形内,那么它很可能是从前一帧移动的同一个标记,然后重新对齐矩形以适应新的标记位置,依此类推。有这么多帧,这个问题可能会使处理速度变慢,因此这个问题。 谢谢和欢呼。

【问题讨论】:

  • 有没有关于矩形的额外信息/知识? (它们是否重叠,轴对齐,...)
  • 另外,使用边界圆而不是矩形不是更好的主意吗? (更容易计算)
  • 轴对齐。总是。
  • 你难道不知道每个点应该在里面吗?你不能使用这些知识吗?您是否真的需要知道标记是否已移动到完全不同的矩形?
  • 试过了吗?在我看来,除非您有 一堆 标记,否则即使您进行了详尽的搜索,您仍然应该能够获得良好的帧速率。并不是我提倡这样。我认为 Lasse 的想法是最好的,但目前实际需要多少时间?

标签: algorithm graphics


【解决方案1】:

改进这种幼稚方法的常用方法是使用Spatial Indexing。有几个data structures 专门研究这个。我敢打赌 OpenCV 已经为您提供了其中一些数据结构。

如何在空间上索引场景的一个简单示例是将场景分解为网格,然后为每个矩形确定矩形包含或相交的网格单元格。然后,您确定您的观点所在的单元格,瞧,您现在可以在一个希望小于天真的方法的矩形列表上进行昂贵的命中测试。

这种算法被称为空间散列,在 2D 游戏中被大量用于加速碰撞检测。请注意,当所有矩形都在每个单元格中,或者当所有矩形和您的点都在同一个单元格中时,该算法的最坏情况会发生。这是一些粗略的伪代码,说明它如何应用于您。不过,我会阅读空间散列,wholearticles 将描述执行此操作的最佳方法。

rects = array of rectangles
grid = divide scene into n x m grid

for each cell in grid do
    cell.m_rects = determine_which_rects_intersect(cell, rects)
end

...

pt = some point in scene
pt_cell = grid.get_cell_for_pt(pt)

hits = empty array
for each rect in pt_cell.m_rects do
    if expensive_hit_test(pt, rect) then
        hits.append(rect)
    end
end

return hits

【讨论】:

  • 您是否阅读了所附链接中的问题?我试图理解这有点新。
  • 将网格视为图像的像素化。创建一个网格作为(标志,整数。矩形标识符列表)的二维数组。将所有矩形放入网格中(打开标志,或将整​​数放入网格[x,y],或添加到列表中)。现在您可以在 O(1) 中检查是否包含在一个矩形中。
  • 他们的一些资源能更好地解释这种方法吗?
  • 如果我的矩形的一半位于网格的一部分,另一半位于网格的另一部分,该怎么办?
  • @SohaibI 在阅读了您的背景信息后,我想您可能会尝试自己跟踪这些标记,这有点过头了。随着时间的推移跟踪 blob 的问题很棘手,并且有很多文章可供阅读。谷歌的功能跟踪和blob跟踪之类的东西。至于我给你的这个算法,它将完成你在这个问题中所要求的,但我认为它不会帮助你告诉你在视频中跟踪特征的更大目标,或者在任何情况下,这个算法只会服务于整个解决方案的一小部分。
【解决方案2】:

【讨论】:

    【解决方案3】:

    问题分为 2 类。

    • 空间复杂性
    • 时间复杂度

    哪一个对你来说更重要?如果它是一个游戏,那么时间复杂度对你来说更重要。您要确保您对该算法的响应时间不仅快,而且具有确定性。快很容易理解,我就不解释了。确定性,意味着每次你运行这个算法时,它都会在确定的时间内返回,否则你的游戏会变慢并且随着时间的推移会变得更糟。要避免的内存堆积。这意味着您在运行此算法时无法分配/取消分配内存。

    如果空间复杂性是您的问题,那么您必须在时间和确定性'主义上妥协。

    算法的唯一解决方案基于一个假设。矩形不随时间变化。在这种情况下,您可以为分辨率上的“每个点”创建一个布尔数组,并在背景算法(蛮力)中确定是否有任何点位于矩形内。这样你的算法就是 O(1)。快速且确定性。

    如果您的矩形随时间变化,那么您需要一个后台进程来事先了解矩形,并在使用您的点进行搜索之前对其进行处理。

    这不是解决方案,只是对您的问题的提示。我希望这会有所帮助。

    【讨论】:

    • 内存不是问题。时间复杂度应该更好,因为需要处理很多帧。这不是游戏,但在时间上仍然需要效率。
    • 我不完全理解你的解决方案,是否说明我应该在后台运行蛮力?
    • 是的,在加载游戏之前,请完成所有处理并保持布尔数组为 O(1) 做好准备
    • 我之前做过几场比赛。闪电快.. :)
    • 不幸的是,我的矩形确实随着每一帧而改变。这就是我算法的关键。
    【解决方案4】:

    第 1 步:根据 x 和 y 轴对点进行排序(这样您就有了两个排序列表)

    第 2 步:对每个矩形在这些列表上进行二分搜索并计算候选集。

    第 3 步:选择较小的候选集并验证另一个轴是否也包含这些点。

    此解决方案的最坏情况复杂度非常糟糕 ( O(mn) ),但对于大多数实际情况,这应该可以正常工作。

    【讨论】:

    • 事实上,在大多数情况下,99% 的情况只有一个点会出现在矩形中。所以它更像是 n 个矩形和 n 个点。
    • 这是最坏情况的复杂性。当大多数点在 xrange 或 yrange 中,但没有在矩形中时,就会发生这种情况。这在国际海事组织中很少见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多