Reputation: 321
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
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:
Upvotes: 5