# Find area of overlapping rectangles in Python / OpenCV with a raw list of points

## Question:

I have the coordinates `x1`, `y1`, `x2`, `y2` of a rectangle and a list of other coordinates for other rectangles.

I want to compare the value of the one I already have over with the others to see if they overlap more than `50%` of the original rectangle.

I checked other resources but still, I could get my head around it:

Let’s first simplify your problem to a single dimension:

You have an interval `A = [a0, a1]` and want to find out how much does another interval `B = [b0, b1]` intersects with it. I will represent `A` with `=` and `B` with `-`.

There are 6 possible scenarios:

• `A` contains `B`, `intersection = b1 - b0`

``````a0  b0  b1  a1
==============
------
``````
• `B` contains `A`, `intersection = a1 - a0`

``````b0  a0  a1  b1
======
--------------
``````
• `B` intersects `A` from the left, `intersection = b1 - a0`

``````b0  a0  b1  a1
==========
----------
``````
• `B` intersects `A` from the right, `intersection = a1 - b0`

``````a0  b0  a1  b1
==========
----------
``````
• `B` is to the left of `A`, `intersection = 0`

``````b0  b1  a0  a1
======
------
``````
• `B` is to the right of `A`, `intersection = 0`

``````a0  a1  b0  b1
======
------
``````

Based on that, we can define a function that, given two intervals `A = [a0, a1]` and `B = [b0, b1]`, returns how much they intersect:

``````def calculateIntersection(a0, a1, b0, b1):
if a0 >= b0 and a1 <= b1: # Contained
intersection = a1 - a0
elif a0 < b0 and a1 > b1: # Contains
intersection = b1 - b0
elif a0 < b0 and a1 > b0: # Intersects right
intersection = a1 - b0
elif a1 > b1 and a0 < b1: # Intersects left
intersection = b1 - a0
else: # No intersection (either side)
intersection = 0

return intersection
``````

That’s pretty much everything you need. To find out how much do two rectangles intersect, you just need to execute this function on both the `X` and the `Y` axis and multiply those amounts to get the intersecting area:

``````# The rectangle against which you are going to test the rest and its area:
X0, Y0, X1, Y1, = [0, 0, 10, 10]
AREA = float((X1 - X0) * (Y1 - Y0))

# Rectangles to check
rectangles = [[15, 0, 20, 10], [0, 15, 10, 20], [0, 0, 5, 5], [0, 0, 5, 10], [0, 5, 10, 100], [0, 0, 100, 100]]

# Intersecting rectangles:
intersecting = []

for x0, y0, x1, y1 in rectangles:
width = calculateIntersection(x0, x1, X0, X1)
height = calculateIntersection(y0, y1, Y0, Y1)
area = width * height
percent = area / AREA

if (percent >= 0.5):
intersecting.append([x0, y0, x1, y1])
``````

The result will be:

• `[15, 0, 20, 10]` does not intersect in the X-axis, so `width = 0`.
• `[0, 15, 10, 20]` does not intersect in the Y-axis, so `height = 0`.
• `[0, 0, 5, 5]` intersects only `25%`.
• `[0, 0, 5, 10]` intersects `50%` and will be added to `intersecting`.
• `[0, 5, 10, 100]` intersects `50%` and will be added to `intersecting`.
• `[0, 0, 100, 100]` intersects `100%` and will be added to `intersecting`.

The overlap area is the product of the overlap width and the overlap height.

To find the width overlap of the rectangles `XY` and `xy`, take the rightmost of the left edges and the leftmost of the right edges. Numerically, `max(X1, x1)` and `min(X2, x2)`. Thus the overlap width is `min(X2, x2) - max(X1, x1)`. If this is negative, there is no overlap at all. Repeat for the height.

Thus, the area of overlap can be expressed with a single formula:

``````max(0, min(X2, x2) - max(X1, x1)) . max(0, min(Y2, y2) - max(Y1, y1))
``````

[Total cost: six comparisons, two subtractions, one product (plus one comparison to the target area).]

As a micro-optimization, you can conclude "no" immediately if

``````min(X2, x2) - max(X1, x1) < 50% (X2 - X1)
``````

[With some probability, the cost is reduced to three comparisons and one subtraction.]

Categories: questions
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.