TLDR: I am trying out the SpeedEstimator
from the solutions
module, however whenever attempt the estimation on a video, all the vehicles get estimated as moving at 0 km/hr.
https://docs.ultralytics.com/reference/solutions/speed_estimation/
This is the code snippet I am using;
import cv2
from ultralytics import YOLO, solutions
# Open the video file
cap = cv2.VideoCapture("/path/to/video")
assert cap.isOpened(), "Error reading video file"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
# Video writer
video_writer = cv2.VideoWriter("annotated_vid.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
# Define region points for speed estimation
line_pts = [(0,0),(w-1,h-1)]
corners = [(0,0),(0,h-1),(w-1,h-1),(w-1,0)] #top-left, bottom-left, bottom-right, top-right
# Initialize speed estimation object
speed_obj = solutions.SpeedEstimator(
reg_pts=line_pts,
#region = corners,
model = '/path/to/yolo-model',
)
while cap.isOpened():
success, im0 = cap.read()
if not success:
print("Video frame is empty or video processing has been successfully completed.")
break
result = speed_obj.process(im0)
output_frame = result.plot_im
video_writer.write(output_frame)
cap.release()
video_writer.release()
cv2.destroyAllWindows()
-
Whenever I set the ROI to any section of the frame including the full frame using the region
keyword, all the vehicles get estimated as moving at 0 km/hr.
-
When I use only reg_pts
, I get some non zero estimations usually 2, 3 or 4 km/hr, but the annotated ROI is this small rectangular section that does not change no matter how much I change the values of the list, and the speed estimates only occur sometimes when the car’s center overlaps with this annotated ROI.
-
When I use reg_pts
and region
together (because with region
I can specify the whole frame etc. and because I only get non-zero estimates with reg_pts
) it resets to default behavior and outputs 0 km/hr for each vehicle.
Hi @muizbello, thanks for reaching out and providing the code snippet.
The parameter to define the speed estimation area is region
, not reg_pts
. This region
should define the boundary line or area that objects need to cross for the speed calculation to trigger.
Looking at the SpeedEstimator
implementation detailed in the Speed Estimation reference documentation, the speed is calculated based primarily on the vertical displacement of the object’s track as it intersects the defined region
, specifically using np.abs(self.track_line[-1][1] - self.trk_pp[track_id][1]) / time_difference
.
This means the current implementation assumes movement across a generally horizontal region boundary. If you define the region
as the entire frame (corners
) or a diagonal line (line_pts
), objects might not cross the boundary in a way that produces significant vertical displacement relative to the frame, leading to near-zero speed estimations.
For best results, try defining region
as a horizontal rectangular area that vehicles will clearly cross, similar to the example in the Speed Estimation guide:
# Example horizontal region
speed_region = [(20, 400), (1080, 400), (1080, 360), (20, 360)]
# Initialize speed estimation object
speed_obj = solutions.SpeedEstimator(
region=speed_region,
model='/path/to/yolo-model',
# Add other necessary args like names if using a custom model
)
Ensure the region
points define an area where you expect vehicles to move across with a noticeable vertical component in the video frame. Remember that this method provides an estimate, and its accuracy depends on factors like camera angle and the object’s movement path relative to the defined region.
Thank you for the quick response, your suggestion helped, once I reduced the region of interest, I started getting non-zero estimations.
Hi @muizbello,
Glad to hear that adjusting the region of interest helped resolve the issue!
The SpeedEstimator
calculates speed based on the change in an object’s vertical position (y
-coordinate) as its track intersects the defined region
. When the region
covers the entire frame or a diagonal line, the intersection logic might not trigger appropriately, or the vertical displacement component used for the calculation could be minimal or zero, especially for horizontal movement, leading to the 0 km/hr estimates.
Using a more constrained, typically horizontal region
(defined by 2 or 4 points across the expected path of motion) ensures that the vertical displacement is measured meaningfully as objects cross that specific area. You can find examples of defining such regions in the Speed Estimation guide.
Let us know if you have any more questions!