检测物体之间距离的最快方法?

时间:2012-02-21 07:29:19

标签: algorithm math opencv

我在3D空间中有未知数量的对象,我想知道检测两个对象或多个对象之间的距离是否小于阈值的最快方法是什么。 我认为那是一个n!问题,但我想要一个更好的解决方法。

我尝试过以下伪代码,我需要你对它的评论。

 for (int y=0; y<blobList.size();y++){
       for (int x =1; x<blobList.size();x++)
       {
           CvPoint *blob_a = new CvPoint();
           CvPoint *blob_b = new CvPoint();
           blob_a->x = blobList[x].second->maxx;
           blob_a->y = blobList[x].second->maxy;
           blob_b->x = blobList[y].second->maxx;
           blob_b->y = blobList[y].second->maxy;

           double dist = distance(blob_a,blob_b);
           cout<< " distance between blob "<<blobList[y].second->label<<"and "<<blobList[x].second->label<<endl;
           cout<<dist<<endl;

           if( dist<ParamMgr.fDistance)
           {

           cout<< " Collision between "<<blobList[y].second->label<<"and "<<blobList[x].second->label<<endl;
           }
           else {
               cout<< " "<<endl;
           }
       }

3 个答案:

答案 0 :(得分:10)

我可以想到三个解决方案,每个解决方案都有不同的时间\空间权衡。

n x n array

如果您有少量的 n 对象和距离函数D(n 1 ,n 2 ),您可以计算提前距离。

创建2D n X n数组。在array [i,j]中存储D的结果(n i ,n j )。

优点:

  • 初始计算后,任何两个对象的答案都在O(1)中给出。
  • 简单

<强>缺点:

  • 大数据集的低效率
  • 无法轻松添加新对象

记忆化

Memoize你的距离功能可以记住之前的通话。

R-树

用于在2D \ 3D对象(如点和Polyhedrons)中存储对象的标准数据结构为R-Trees。简而言之,您的对象被分组为附近项目的3D立方体。它提供了log(n)时间的有效插入和查找时间,并且阈值距离查找非常有效,尤其是当答案为负时。

引用Wikipedia article

  

R树常见的实际用法可能是存储...典型地图的多边形   由以下部分组成:街道,建筑物,湖泊轮廓,海岸线等。   然后快速找到答案,例如“查找所有博物馆”   在我当前位置2公里范围内“,”检索所有路段   距离我的位置不到2公里“

  

数据结构的关键思想是将附近的对象分组   用下一个最小边界矩形表示它们   更高层次的树; R树中的“R”表示矩形。

你在大多数现代编程语言中都有R-Tree实现。

enter image description here

答案 1 :(得分:1)

如果3D空间有限,那么我们可以将空间划分为小立方体。每条边的长度是值阈值。我们假设它为 d 。然后,我们将对象放入多维数据集中。选取包含对象的多维数据集 B(x_i,y_j,z_k)。然后我们只检查相邻的立方体。最多,对于每个立方体,我们将有27个立方体,包括它自己。我们可以忽略其他立方体,因为它们的距离肯定远远超过阈值。

此解决方案仅适用于节点稀疏的情况。如果所有节点都在空间 3d * 3d * 3d 中。然后算法将处于最坏的情况。您可以不过滤任何节点。

答案 2 :(得分:1)

Looking for a non "brute force" algorithm to remove intersecting areas of a collection of Rects的公认解决方案类似,您可以在x,y或z维度之一中对对象进行排序,并且对于每个对象,只需按阈值在排序列表中向前搜索(可能缩放到考虑额外的尺寸)。这将至少为您提供绝对不靠近的所有对象。对于剩下的,您可以检查它们的距离并做出决定,或者更好的方法是将其他尺寸划分为多个相等大小的部分,并且如果其j维值在其中,则将每个对象分类为在一个部分中。部分。您可以更快地决定对象是否明确超出阈值。总的来说,对于给定的对象,这种方法会将实际距离计算的数量减少到很少,并且问题会有效地扩大。