Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate overlapped area between two rectangles

enter image description here

I want to calculate the overlapped area "THE GRAY REGION" between red and blue rectangles.

Each rectangle is defined by its four corner coordinates. The resulted unit of the overlapped area is unit square.

I could not imagine how can I do it?

Any creative comments would be appreciated.

like image 964
Eric Bal Avatar asked Nov 26 '14 15:11

Eric Bal


People also ask

Do you check if two rectangles overlap with each other?

Two rectangles do not overlap if one of the following conditions is true. 1) One rectangle is above top edge of other rectangle. 2) One rectangle is on left side of left edge of other rectangle.

What does area of overlap mean?

overlap noun (SAME AREA) the amount by which two things or activities cover the same area: The roof tiles will need an overlap of several centimetres.


3 Answers

This type of intersection is easily done by the "min of the maxes" and "max of the mins" idea. To write it out one needs a specific notion for the rectangle, and, just to make things clear I'll use a namedtuple:

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 

If you don't like the namedtuple notation, you could just use:

dx = max(a[0], b[0]) - min(a[2], b[2])

etc, or whatever notation you prefer.

like image 82
tom10 Avatar answered Oct 02 '22 07:10

tom10


As this question has a shapely tag, here is a solution using it. I will use the same rectangles as in the tom10 answer:

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

This is much more concise than the version in the accepted answer. You don't have to construct your own Rectangle class as Shapely already provides the ready ones. It's less error-prone (go figure out the logic in that area function). And the code itself is self-explanatory.


References:
Docs for object.intersection(other) method

like image 32
Georgy Avatar answered Oct 02 '22 08:10

Georgy


Since the post is very related to computer vision and object detection, I thought of putting some code together that I use for finding the intersection of bounding boxes and also finding their intersection over union (IoU). This code was originally developed by Adrian Rosebrock in this blog post:

This is the module (where I named it 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

And to use it:

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

result = a.intersect(b)
like image 37
Masoud Masoumi Moghadam Avatar answered Oct 02 '22 09:10

Masoud Masoumi Moghadam