The image shows two green rectangles. I need to manually draw each rectangle in the video and have the coordinates saved in area1 and area2 of the script (main), respectively. I attach the two scripts I use (main and tracker).enter image description here
I attach the two scripts (main and tracker)
main
import cv2
import pandas as pd
from ultralytics import YOLO
from tracker import*
import cvzone
import numpy as np
model=YOLO('yolov8s.pt')
def RGB(event, x, y, flags, param):
if event == cv2.EVENT_MOUSEMOVE :
point = [x, y]
print(point)
cv2.namedWindow('RGB')
cv2.setMouseCallback('RGB', RGB)
cap=cv2.VideoCapture('p.mp4')
my_file = open("coco.txt", "r")
data = my_file.read()
class_list = data.split("n")
#print(class_list)
count=0
tracker=Tracker()
area1=[(494,289),(505,499),(578,496),(530,292)]
area2=[(548,290),(600,496),(637,493),(574,288)]
going_out={}
going_in={}
counter1=[]
counter2=[]
while True:
ret,frame = cap.read()
if not ret:
break
# frame = stream.read()
# count += 1
# if count % 3 != 0:
# continue
frame=cv2.resize(frame,(1020,500))
results=model.predict(frame)
# print(results)
a=results[0].boxes.data
px=pd.DataFrame(a).astype("float")
# print(px)
list=[]
for index,row in px.iterrows():
# print(row)
x1=int(row[0])
y1=int(row[1])
x2=int(row[2])
y2=int(row[3])
d=int(row[5])
c=class_list[d]
if 'person' in c:
list.append([x1,y1,x2,y2])
bbox_idx=tracker.update(list)
for bbox in bbox_idx:
x3,y3,x4,y4,id=bbox
result=cv2.pointPolygonTest(np.array(area2,np.int32),((x4,y4)),False)
if result>=0:
going_out[id]=(x4,y4)
if id in going_out:
result1=cv2.pointPolygonTest(np.array(area1,np.int32),((x4,y4)),False)
if result1>=0:
cv2.circle(frame,(x4,y4),7,(255,0,255),-1)
cv2.rectangle(frame,(x3,y3),(x4,y4),(255,255,255),2)
cvzone.putTextRect(frame,f'{id}',(x3,y3),1,1)
if counter1.count(id)==0:
counter1.append(id)
result2=cv2.pointPolygonTest(np.array(area1,np.int32),((x4,y4)),False)
if result2>=0:
going_in[id]=(x4,y4)
if id in going_in:
result3=cv2.pointPolygonTest(np.array(area2,np.int32),((x4,y4)),False)
if result3>=0:
cv2.circle(frame,(x4,y4),7,(255,0,255),-1)
cv2.rectangle(frame,(x3,y3),(x4,y4),(255,0,0),2)
cvzone.putTextRect(frame,f'{id}',(x3,y3),1,1)
if counter2.count(id)==0:
counter2.append(id)
out_c=(len(counter1))
in_c=(len(counter2))
cvzone.putTextRect(frame,f'OUT:{out_c}',(50,60),2,2)
cvzone.putTextRect(frame,f'IN:{in_c}',(50,160),2,2)
cv2.polylines(frame,[np.array(area1,np.int32)],True,(0,255,0),2)
cv2.polylines(frame,[np.array(area2,np.int32)],True,(0,255,0),2)
cv2.imshow("RGB", frame)
if cv2.waitKey(1)&0xFF==27:
break
cap.release()
cv2.destroyAllWindows()
tracker
import math
class Tracker:
def __init__(self):
# Store the center positions of the objects
self.center_points = {}
# Keep the count of the IDs
# each time a new object id detected, the count will increase by one
self.id_count = 0
def update(self, objects_rect):
# Objects boxes and ids
objects_bbs_ids = []
# Get center point of new object
for rect in objects_rect:
x, y, w, h = rect
cx = (x + x + w) // 2
cy = (y + y + h) // 2
# Find out if that object was detected already
same_object_detected = False
for id, pt in self.center_points.items():
dist = math.hypot(cx - pt[0], cy - pt[1])
if dist < 35:
self.center_points[id] = (cx, cy)
# print(self.center_points)
objects_bbs_ids.append([x, y, w, h, id])
same_object_detected = True
break
# New object is detected we assign the ID to that object
if same_object_detected is False:
self.center_points[self.id_count] = (cx, cy)
objects_bbs_ids.append([x, y, w, h, self.id_count])
self.id_count += 1
# Clean the dictionary by center points to remove IDS not used anymore
new_center_points = {}
for obj_bb_id in objects_bbs_ids:
_, _, _, _, object_id = obj_bb_id
center = self.center_points[object_id]
new_center_points[object_id] = center
# Update dictionary with IDs not used removed
self.center_points = new_center_points.copy()
return objects_bbs_ids
Micky is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3