Javier Alonso Delgado
Javier Alonso Delgado

Reputation: 321

OpenCV - How to detect intersection bewteen two rectangles?

I am implementing a kind of alarm system with OpenCV. I need to track a person inside a "safe area", and detect and notify is he's going out of bounds.

I have implemented the motion tracking. Now I need to define a ROI (safe zone rectangle on the floor; the camera is on the ceiling) and detect the intersection between it and the person's bounding rectangle.

Something similar to this.

I have the following:

while True:
 
    # Grab frame from webcam
    ret, color_frame = vid.read()

    # resize the frame, convert it to grayscale, and blur it
    color_frame = imutils.resize(color_frame, width=500)
    gray = cv2.cvtColor(color_frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (21, 21), 0)

    # MOTION TRACKING #
    # Defining safe zone area on the floor.
    roi = cv2.rectangle(color_frame, (50, 50), (500, 500), (0, 0, 0), 2)

    # First frame to compare motion
    if firstFrame is None:
        firstFrame = gray
        continue

    # Absolute difference to detect changes.
    frameDelta = cv2.absdiff(firstFrame, gray)
    thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]

    # Finding contours
    thresh = cv2.dilate(thresh, None, iterations=2)
    contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = imutils.grab_contours(contours)

    # Filtering contours
    for c in contours:
        # if the contour is too small, ignore it
        if cv2.contourArea(c) < 5000:
            continue

        # Bounding Rect for the person which we are tracking
        (x, y, w, h) = cv2.boundingRect(c)
        boudingRect = cv2.rectangle(color_frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

As I said, the person is inside the ROI area, and now I need to detect if he's going out of bounds. The final idea is to notify via sound alarm, but I am mainly struggling with the intersection detection inside that loop.

Upvotes: 3

Views: 1737

Answers (1)

Vatsal Parsaniya
Vatsal Parsaniya

Reputation: 899

This will help you understand how you can implement an intersection between two rectangles using cv2.pointPolygonTest for more about pointPolygonTest you can find it here

import cv2
import numpy as np


def check_intersection(polygon1, polygon2):
    intersection = False
    for point in polygon2:
        result = cv2.pointPolygonTest(polygon1, tuple(point), measureDist=False)
        # if point inside return 1
        # if point outside return -1
        # if point on the contour return 0

        if result == 1:
            intersection = True

    return intersection


image1 = np.zeros((300, 300), dtype=np.uint8)
image2 = np.zeros((300, 300), dtype=np.uint8)

# take 4 points of
rectangle1_cordinates = np.array([[50, 50], [50, 100], [100, 100], [100, 50]])
rectangle2_cordinates = np.array([[75, 75], [75, 125], [125, 125], [125, 75]])
rectangle3_cordinates = np.array([[110, 110], [110, 160], [160, 160], [160, 110]])

result_1_and_2 = check_intersection(rectangle1_cordinates, rectangle2_cordinates)
result_1_and_3 = check_intersection(rectangle1_cordinates, rectangle3_cordinates)

cv2.putText(image1, str(result_1_and_2), (20, 20), cv2.FONT_HERSHEY_COMPLEX, 0.8, 255, 1)
cv2.drawContours(image1, [rectangle1_cordinates], -1, 255, 2)
cv2.drawContours(image1, [rectangle2_cordinates], -1, 255, 2)

cv2.putText(image2, str(result_1_and_3), (20, 20), cv2.FONT_HERSHEY_COMPLEX, 0.8, 255, 1)
cv2.drawContours(image2, [rectangle1_cordinates], -1, 255, 2)
cv2.drawContours(image2, [rectangle3_cordinates], -1, 255, 2)

cv2.imshow("image1", image1)
cv2.imshow("image2", image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output:

enter image description here

Upvotes: 5

Related Questions