计算两个矩形之间的重叠区域

Eri*_*Bal 20 python numpy polygon matplotlib shapely

在此输入图像描述

我想计算红色和蓝色矩形之间的重叠区域"THE GREY REGION".

每个矩形由其四个角坐标定义.重叠区域的结果单位是单位平方.

我无法想象我该怎么办?

任何有创意的评论将不胜感激.

tom*_*m10 39

这种类型的交叉点很容易通过"最小值"和"最大值"的想法来完成.要写出来,需要一个矩形的特定概念,并且,为了清楚起见,我将使用一个命名元组:

from collections import namedtuple
Rectangle = namedtuple('Rectangle', 'xmin ymin xmax ymax')

ra = Rectangle(3., 3., 5., 5.)
rb = Rectangle(1., 1., 4., 3.5)
# intersection here is (3, 3, 4, 3.5), or an area of 1*.5=.5

def area(a, b):  # returns None if rectangles don't intersect
    dx = min(a.xmax, b.xmax) - max(a.xmin, b.xmin)
    dy = min(a.ymax, b.ymax) - max(a.ymin, b.ymin)
    if (dx>=0) and (dy>=0):
        return dx*dy

print area(ra, rb)
#  0.5 
Run Code Online (Sandbox Code Playgroud)

如果你不喜欢namedtuple表示法,你可以使用:

dx = max(a[0], b[0]) - min(a[2], b[2])
Run Code Online (Sandbox Code Playgroud)

等等,或者你喜欢的任何表示法.

  • @just:是的,无论哪种方式都有效.使用max和min方法只是一种简单的方法,可以用来确定相对位置的复杂条件集.也就是说,读取"max(a.xmin,b.xmin)"作为"最左边的角落"等.此外,我改变了我的答案,现在包括矩形不相交的情况. (2认同)

Geo*_*rgy 7

由于这个问题的标签很,因此这里是一个使用它的解决方案。我将使用与tom10答案相同的矩形:

from shapely.geometry import Polygon

polygon = Polygon([(3, 3), (5, 3), (5, 5), (3, 5)])
other_polygon = Polygon([(1, 1), (4, 1), (4, 3.5), (1, 3.5)])
intersection = polygon.intersection(other_polygon)
print(intersection.area)
# 0.5
Run Code Online (Sandbox Code Playgroud)

这比接受的答案中的版本要简洁得多。Rectangle因为Shapely已经提供了现成的类,所以您不必构造自己的类。它不太容易出错(请弄清楚该area函数中的逻辑)。而且代码本身是不言自明的。


参考文献:方法
文档object.intersection(other)


Mas*_*dam 7

由于这篇文章与计算机视觉和对象检测非常相关,因此我想将一些代码放在一起,用于查找边界框的交集并查找它们的并集交集 (IoU)。该代码最初由 Adrian Rosebrock 在这篇博文中开发:

这是模块(我将其命名为Bbox):

class Bbox:
    def __init__(self, x1, y1, x2, y2):
        self.x1 = max(x1, x2)
        self.x2 = min(x1, x2)
        self.y1 = max(y1, y2)
        self.y2 = max(y1, y2)
        self.box = [self.x1, self.y1, self.x2, self.y2]
        self.width = abs(self.x1 - self.x2)
        self.height = abs(self.y1 - self.y2)

    @property
    def area(self):
        """
        Calculates the surface area. useful for IOU!
        """
        return (self.x2 - self.x1 + 1) * (self.y2 - self.y1 + 1)

    def intersect(self, bbox):
        x1 = max(self.x1, bbox.x1)
        y1 = max(self.y1, bbox.y1)
        x2 = min(self.x2, bbox.x2)
        y2 = min(self.y2, bbox.y2)
        intersection = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1)
        return intersection

    def iou(self, bbox):
        intersection = self.intersection(bbox)

        iou = intersection / float(self.area + bbox.area - intersection)
        # return the intersection over union value
        return iou
Run Code Online (Sandbox Code Playgroud)

并使用它:

a = Bbox([516, 289, 529, 303])
b = Bbox([487, 219, 533, 342])

result = a.intersect(b)
Run Code Online (Sandbox Code Playgroud)