So far, I've been able to successfully implement a polygon zone counting and one single line zone counter of in/out
However, when I tried implementing multiple linezones counters, I found that they get triggered by every single object detected in the frame
In this screenshot you can see how each line gets triggered by every single object inside the detection area

import supervision as sv
import numpy as np
# Person, cats, dogs, vehicles, boats, knives, scissors, street signs
#classes=[0,1,2,3,5,6,7,8,11,14,15,16,24,25,26,28,42,43,44]
if __name__ == "__main__":
# Load the model
model = YOLO("yolov8x.pt")
# Open a connection to the webcam
cap = cv2.VideoCapture('Samples/highway1.mp4')
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# Set window dimensions (Only works on my laptop's webcam??)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)
# Area of Interest parameters
# Polygon for area of detections
polygon = np.array([
[0, 390], # A
[1280, 390], # B
[1280, 720], # C
[0, 720] # D
])
# TEST LINE
testline_start = sv.Point(360, 360)
testline_end = (400, 400)
testline_zone = sv.LineZone(start=testline_start, end=testline_end)
testline_annotator = sv.LineZoneAnnotator()
# LEFT SIDE LINES
# Line 1
line1_start = sv.Point(69, 490)
line1_end = sv.Point(200, 490)
# Line 2
line2_start = sv.Point(110, 557)
line2_end = sv.Point(258, 557)
# Line 3
line3_start = sv.Point(315, 527)
line3_end = sv.Point(456, 527)
# RIGHT SIDE LINES
# Line 4
line4_start = sv.Point(803, 502)
line4_end = sv.Point(926, 502)
# Line 5
line5_start = sv.Point(1012, 570)
line5_end = sv.Point(1181, 570)
# Line 6
line6_start = sv.Point(1050, 482)
line6_end =sv.Point(1173, 482)
# Initiate polygon annotators
Polygon = sv.PolygonZone(polygon=polygon, frame_resolution_wh=[frame_width, frame_height])
Polygon_Annotator = sv.PolygonZoneAnnotator(zone=Polygon, color=sv.Color.white(), thickness=2, text_thickness=2, text_scale=1)
# Initialize bounding boxes annotator
Box_Annotator = sv.BoxAnnotator(thickness=2, text_thickness=1, text_scale=0.5)
# Initialize lines annotators
Line1 = sv.LineZone(start=line1_start, end=line1_end)
Line1_Annotator = sv.LineZoneAnnotator(thickness=1, text_thickness=1, text_scale=0.4)
Line2 = sv.LineZone(start=line2_start, end=line2_end)
Line2_Annotator = sv.LineZoneAnnotator(thickness=1, text_thickness=1, text_scale=0.4)
Line3 = sv.LineZone(start=line3_start, end=line3_end)
Line3_Annotator = sv.LineZoneAnnotator(thickness=1, text_thickness=1, text_scale=0.4)
Line4 = sv.LineZone(start=line4_start, end=line4_end)
Line4_Annotator = sv.LineZoneAnnotator(thickness=1, text_thickness=1, text_scale=0.4)
Line5 = sv.LineZone(start=line5_start, end=line5_end)
Line5_Annotator = sv.LineZoneAnnotator(thickness=1, text_thickness=1, text_scale=0.4)
Line6 = sv.LineZone(start=line6_start, end=line6_end)
Line6_Annotator = sv.LineZoneAnnotator(thickness=1, text_thickness=1, text_scale=0.4)
# Define the window name
window_name = 'Video file'
while True:
# Read a frame from the video file
ret, frame = cap.read()
# If the frame was successfully read
if ret:
# Predict
for result in model.track(frame, device='0', classes=[2, 3, 4, 7, 8], tracker='botsort.yaml', stream=True):
# Get detections results for Supervision
detections = sv.Detections.from_yolov8(result)
# Polygon triggers
mask = Polygon.trigger(detections=detections)
detections = detections[mask]
# Only get tracker ids if we actually have detections, otherwise will give NoneType error
if result.boxes.id is not None:
detections.tracker_id = result.boxes.id.cpu().numpy().astype(int)
# Get labels to draw on each detected object
labels = []
for detection in detections:
xyxy, mask, confidence, class_id, tracker_id = detection
if class_id is not None and confidence is not None:
labels.append(f"#{tracker_id} {model.model.names[class_id]} {confidence:0.2f}")
# Draw the labels
frame = Box_Annotator.annotate(frame, detections=detections, labels=labels)
# Draw Polygon
frame = Polygon_Annotator.annotate(scene=frame)
# Draw the line
Line1_Annotator.annotate(frame, Line1)
Line2_Annotator.annotate(frame, Line2)
Line3_Annotator.annotate(frame, Line3)
Line4_Annotator.annotate(frame, Line4)
Line5_Annotator.annotate(frame, Line5)
Line6_Annotator.annotate(frame, Line6)
testline_annotator.annotate(frame, testline_zone)
# Line triggers
Line1.trigger(detections=detections)
Line2.trigger(detections=detections)
Line3.trigger(detections=detections)
Line4.trigger(detections=detections)
Line5.trigger(detections=detections)
Line6.trigger(detections=detections)
testline_zone.trigger(detections=detections)
# Show video
cv2.imshow(window_name, frame)
# If the user presses 'q', or the window is closed, exit the loop
if cv2.waitKey(1) & 0xFF == ord('q') or cv2.getWindowProperty(window_name, cv2.WND_PROP_VISIBLE) < 1:
break
else:
print("Unable to read frame")
break
# Release the webcam and destroy all windows
cap.release()
cv2.destroyAllWindows()
Search before asking
Bug
Hello everyone,
I have been trying to play around with YoloV8 and Supervision for traffic lanes monitoring
So far, I've been able to successfully implement a polygon zone counting and one single line zone counter of in/out
However, when I tried implementing multiple linezones counters, I found that they get triggered by every single object detected in the frame
In my scenario:
2 ways highways with each way having 4 lanes
I have set up 1 Line for each lane in both directions of the highways
When I run my program, the Lines' counters get updated as if they were triggered by every single car inside the frame
In this screenshot you can see how each line gets triggered by every single object inside the detection area

Environment
Minimal Reproducible Example
I was unable to figure out which part of my code caused the issue
Additional
Yes
Are you willing to submit a PR?