2017-09-29 73 views
0

我想要计算两个矩形之间的交集的交集IoU,这两个矩形的轴未对齐,但轴的角度小于30度。近似值也被查找。计算轴未对齐的两个矩形之间的交集区域

一个可能的解决方案是检查两个矩形之间的角度是否小于30度,并将它们平行旋转以便轴线对齐。从这里可以很容易计算出IoU

另一种可能性是使用蒙特卡洛方法的交叉点(生成点,发现如果该点是在某些行一个矩形的并在另一个之上的一些线),但因为我需要使用此这似乎昂贵计算大量次数。

我一直在跳跃,那里有更好的东西;也许是几何图书馆,或者可能是计算机视觉人员的一种算法。

我想学习使用深度神经网络来掌握位置。我的算法应该预测rgb图像中对象的边界框(矩形)。对于任何图像我也有地面实况(另一个矩形)边界框。从这两个矩形我需要IoU

有什么想法?

回答

1

由于您使用的是Python,我认为Shapely包可以满足您的需求。

+0

确实。但是,意外的是它比我从互联网上收集的速度慢了3倍。此外,对于一个多边形,它显示的结果是我发现的结果的两倍。我不知道为什么。对于矩形,它们都是相同的。 – prometeu

0

This might help

有关使用勾股定理是什么?既然你有两个矩形,当它们相交时,你将会有一个或多个三角形,每个都有一个90°的角度。由于您还知道两个矩形(在我的示例中为20°)之间的角度,以及每个矩形的坐标,因此您可以使用适当的函数(cos/sin/tan)来知道所有的长度三角形的边缘。

我希望这可以帮助

1

有相当有效的算法有两个凸多边形,在奥罗克书“用C计算几何”中描述的交叉计算。

C代码可用at the book page(convconv)。

算法遍历第一个多边形的边,检查第二个多边形顶点的方向以检测交点。当两个随后的顶点位于边的不同侧时,就会发生交叉(这里有很多特技例)。算法大纲是here

+0

Thx,但这对我的任务来说太过于矫枉过正,而且理解C代码和在python中编写代码可能会带来负面影响。我总是只有两个矩形。如果你能想到任何近似值(在问题中提到的条件下)将会非常感激。 – prometeu

+0

你还没有提到 - 两个矩形是否有相似的方向(旋转角度)。你为什么强调30度 - 在这个角度什么是特殊的?在这种情况下,我无法想象任何估算方法都比精确解决方案简单。 – MBo

+0

矩形不具有相同的方向。如果预测的矩形与地面实景矩形(标记的数据图像)的方向大于30度,则不会被接受。如果方向小于30度,机器人的抓手仍然可以抓住物体。所以,矩形实际上是把握位置。我想到的一个近似值是这样的:** 1。**检查矩形的方向是否小于30度** 2 **围绕它们各自中心的轴旋转它们两个轴直到图像取向** 3 * *容易计算_IoU_。 – prometeu

1

您可以考虑一些数值方法,将矩形实际上“渲染”为一些“画布”/画布,并遍历像素以进行统计。画布的大小应该是整个场景边界框的大小,实际上您可以通过选取每个轴出现的最小和最大坐标来找到该大小。 1)“大多数CG”的方法:真的得到一个渲染库,渲染一个矩形与红色,其他矩形与透明的蓝色。然后访问每个像素,如果它具有非0红色分量,则它属于第一个矩形,如果它具有非0蓝色分量,则它属于第二个矩形。如果它有两个,它也属于交叉点。这种方法对编码来说很便宜,但即使在渲染阶段,也需要写入和读取画布,这比写作要慢。这甚至可以在GPU上完成,虽然我不确定安装成本和获得的结果是不会减轻这样一个简单场景的好处。

2)为了提高速度,另一个CG方法会渲染成2个数组,最好是每个像素1个字节(为了找到这种专用信息,您可能需要稍微回顾一下渲染库)。 3)由于写入和读取像素需要时间,所以可以做一些快捷方式,但它需要更多的编码:凸形(凸形)可以通过收集每条扫描线的最小和最大坐标,并在两者之间填充来渲染。如果你自己做,你可以节省填充部分,并且最后还可以读取和检查每个像素的步骤。建立这样的最小 - 最大列表两个矩形,然后你“只是”需要检查他们的关系/为了让每个扫描线,识别重叠

再有就是数学方式:这是不是真的有用,看编辑在以下,而不太可能找到一些用于计算相交面积的理想算法,特别是对于矩形的情况,如果您找到三角形的这种算法,这很可能就足够了。两个矩形可以分成两个三角形,分别为1A + 1B和2A + 2B,然后您只需运行4次这样的算法:1A-2A,1A-2B,1B-2A,1B-2B,将结果和那就是你的交集区域。

编辑:对于数学方法(虽然这也来自图形),我认为https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm可以在这里应用(因为两个矩形都是凸多边形,AB和BA应该产生相同的结果)以找到相交多边形,并且那么剩下的任务就是计算该多边形的面积(这里现在我认为它将是凸面的,然后它很容易)。

+0

Thx为您的答案。我会查一下。但是与此同时,CG代表什么? – prometeu

+0

@prometeu这部分很简单:CG = Computer Graphics :-) – tevemadar

+0

我会给Sutherland-Hodgson算法一些想法。你能告诉我你对我近似的看法,我在MBo的答案中评论过吗?谢谢。 – prometeu

0

我结束了使用,因为这功能实现萨瑟兰-Hodgman算法:

def clip(subjectPolygon, clipPolygon): 
    def inside(p): 
     return(cp2[0]-cp1[0])*(p[1]-cp1[1]) > (cp2[1]-cp1[1])*(p[0]-cp1[0]) 

    def computeIntersection(): 
     dc = [ cp1[0] - cp2[0], cp1[1] - cp2[1] ] 
     dp = [ s[0] - e[0], s[1] - e[1] ] 
     n1 = cp1[0] * cp2[1] - cp1[1] * cp2[0] 
     n2 = s[0] * e[1] - s[1] * e[0] 
     n3 = 1.0/(dc[0] * dp[1] - dc[1] * dp[0]) 
     return [(n1*dp[0] - n2*dc[0]) * n3, (n1*dp[1] - n2*dc[1]) * n3] 

    outputList = subjectPolygon 
    cp1 = clipPolygon[-1] 

    for clipVertex in clipPolygon: 
     cp2 = clipVertex 
     inputList = outputList 
     outputList = [] 
     s = inputList[-1] 

     for subjectVertex in inputList: 
     e = subjectVertex 
     if inside(e): 
      if not inside(s): 
       outputList.append(computeIntersection()) 
      outputList.append(e) 
     elif inside(s): 
      outputList.append(computeIntersection()) 
     s = e 
     cp1 = cp2 
    return(outputList) 

def PolygonArea(corners): 
    n = len(corners) # of corners 
    area = 0.0 
    for i in range(n): 
     j = (i + 1) % n 
     area += corners[i][0] * corners[j][1] 
     area -= corners[j][0] * corners[i][1] 
    area = abs(area)/2.0 
    return area 

intersection = clip(rec1, rec2) 
intersection_area = PolygonArea(intersection) 
iou = intersection_area/(PolygonArea(rec1)+PolygonArea(rec2)-intersection_area) 

另一种慢的方式(不知道是什么算法)可以是:

from shapely.geometry import Polygon 

p1 = Polygon(rec1) 
p2 = Polygon(rec2) 
inter_sec_area = p1.intersection(rec2).area 
iou = inter_sec_area/(p1.area + p2.area - inter_sec_area) 

值得一提的是,在只有一个较大的多边形(不是我的情况)的情况下,shapely模块的面积比第一个方法大两倍。我没有深入地测试两种方法。