es/guides/speed-estimation/ #8975
Replies: 6 comments 6 replies
-
How can i calculate the line_pts? |
Beta Was this translation helpful? Give feedback.
-
Como puedo almacenar las velocidades, y como hacer que las velocidades sean mas precisas? lo corro con diferentes modelos y las velocidades son diferentes |
Beta Was this translation helpful? Give feedback.
-
I am trying to determine whether a person is walking or running inside a shopping center, but the options I see are to draw a line and determine their speed. I would like to know if it is possible to identify the person and, through their tracker_id, be able to determine if they are running or walking anywhere in the video. Is this possible? |
Beta Was this translation helpful? Give feedback.
-
I am trying to determine whether a person is walking or running inside a shopping center, but the options I see are to draw a line and determine their speed. I would like to know if it is possible to identify the person and, through their tracker_id, be able to determine if they are running or walking anywhere in the video. Is this possible? |
Beta Was this translation helpful? Give feedback.
-
thank you so much!
It is of great help to me.
I would like to know if it is possible that it is not just obtaining a
line, but rather being able to detect it anywhere on the screen! taking
into account that it could be close or far from the camera and that this
does not affect the speed.
El mié, 10 jul 2024 a la(s) 2:32 p.m., Glenn Jocher (
***@***.***) escribió:
… @roscha10 <https://github.com/roscha10> hello!
Yes, it is indeed possible to determine whether a person is walking or
running inside a shopping center using Ultralytics YOLOv8 by leveraging
object tracking and speed estimation. Here's a concise guide on how you can
achieve this:
1.
*Object Detection and Tracking*: First, detect and track the person
across frames using YOLOv8. This will help you maintain a consistent
tracker_id for each individual.
2.
*Speed Estimation*: Calculate the speed of the tracked person by
measuring the distance they travel between frames and using the frame rate
of the video.
Here’s a sample code snippet to get you started:
import cv2from ultralytics import YOLO, solutions
# Load the YOLOv8 modelmodel = YOLO("yolov8n.pt")names = model.model.names
# Open the video filecap = cv2.VideoCapture("path/to/video/file.mp4")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 writervideo_writer = cv2.VideoWriter("speed_estimation.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
# Define region points for speed estimationline_pts = [(0, 360), (1280, 360)]
# Initialize SpeedEstimatorspeed_obj = solutions.SpeedEstimator(
reg_pts=line_pts,
names=names,
view_img=True,
)
while cap.isOpened():
success, im0 = cap.read()
if not success:
print("Video frame is empty or video processing has been successfully completed.")
break
# Track objects in the frame
tracks = model.track(im0, persist=True, show=False)
# Estimate speed
im0 = speed_obj.estimate_speed(im0, tracks)
video_writer.write(im0)
cap.release()video_writer.release()cv2.destroyAllWindows()
Key Points:
- *Tracking*: Use model.track() to maintain consistent tracking IDs
for individuals.
- *Speed Estimation*: Use solutions.SpeedEstimator to calculate the
speed based on tracked positions.
For more detailed information and additional resources, please refer to
our Speed Estimation Guide
<https://docs.ultralytics.com/guides/speed-estimation/>.
Feel free to reach out if you have any further questions or need
additional assistance!
—
Reply to this email directly, view it on GitHub
<#8975 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A7E5FJPNFDQDQE3LQXHBCZ3ZLV42PAVCNFSM6AAAAABEYVIZNWVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTAMBRGMZTQMI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***
com>
|
Beta Was this translation helpful? Give feedback.
-
We have tried to adjust the speed thresholds based on the size of the
bounding box, which represents the distance of the person from the camera.
Although this approach helped partially, it did not completely solve the
problem. Detections close to the camera often resulted in
misclassifications such as "running" when the person was barely moving.
We also implemented a time window to smooth out rapid changes in speeds and
states, using a moving average. While this improved the stability of the
states (stop, move, run), there were still inconsistencies and delayed
responses in detection when a person entered the moving frame.
Additionally, we adjusted the refresh rate to more quickly detect when a
person entered the frame. Despite the improvement in initial detection
speed, the system still had accuracy and consistency issues, especially
when people were close to the camera.
The main problem lies in the distance to the camera. Speed perception is
significantly affected by the person's distance from the camera. People
close to the camera appear to move faster than those further away, making
it difficult to correctly classify their movements.
Setting the detection region to cover the entire camera area has added
another layer of complexity. This approach has made it difficult to
maintain accuracy and consistency in motion detection.
We've considered using segmentation to focus on specific parts of the body
(such as leg joints) to determine movement more accurately. However, some
help or options that have effectively resolved the problem would be nice.
Segmentation requires high precision and confidence in detecting body parts.
I really appreciate the time you take to answer my questions. I am very
grateful for your help and guidance. I hope you can help me with this part
and I attach the code we have reached so far.
import cv2
import numpy as np
from collections import defaultdict, deque
from statistics import mean, mode, StatisticsError
from ultralytics import YOLO
model = YOLO("./yolov8n.pt")
names = model.model.names
cap = cv2.VideoCapture("./test/counter.mp4")
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))
base_stopping_threshold = 0.05 # Umbral base para considerar que una
persona está detenida
base_running_threshold = 0.3 # Umbral base para considerar que una persona
está corriendo
# Diccionario para almacenar las posiciones previas de las personas
detectadas
previous_positions = defaultdict(deque)
all_speeds = []
state_windows = defaultdict(deque) # Ventanas de tiempo para suavizar
estados
def ajustar_umbral(area):
"""Ajustar los umbrales de velocidad en función del área del bounding
box."""
if area > 20000: # Si el área es muy grande, la persona está muy cerca
de la cámara
stopping_threshold = base_stopping_threshold * 5
running_threshold = base_running_threshold * 5
elif area > 10000: # Si el área es grande, la persona está cerca de la
cámara
stopping_threshold = base_stopping_threshold * 3
running_threshold = base_running_threshold * 3
elif area > 5000: # Si el área es mediana, la persona está a una
distancia media
stopping_threshold = base_stopping_threshold * 2
running_threshold = base_running_threshold * 2
else: # Si el área es pequeña, la persona está lejos de la cámara
stopping_threshold = base_stopping_threshold
running_threshold = base_running_threshold * 0.5
return stopping_threshold, running_threshold
def determinar_estado(velocidades, stopping_threshold, running_threshold):
"""Determinar el estado basado en una lista de velocidades."""
if all(v < stopping_threshold for v in velocidades):
return "stopping"
elif all(v > running_threshold for v in velocidades):
return "running"
else:
return "moving"
while cap.isOpened():
success, frame = cap.read()
if not success:
print("Video frame is empty or video processing has been
successfully completed.")
break
results = model(frame)
# Extraer detecciones
detections = results[0].boxes
boxes = detections.xyxy.cpu().numpy() if detections else []
confs = detections.conf.cpu().numpy() if detections else []
clss = detections.cls.cpu().numpy() if detections else []
current_positions = {}
speeds = {}
for i in range(len(boxes)):
x1, y1, x2, y2 = boxes[i]
conf = confs[i]
cls = clss[i]
if names[int(cls)] == "person" and conf > 0.4:
cx, cy = int((x1 + x2) / 2), int((y1 + y2) / 2)
# Calcular el área del bounding box
area = (x2 - x1) * (y2 - y1)
if area == 0:
continue
# Ajustar los umbrales de velocidad basado en el área
stopping_threshold, running_threshold = ajustar_umbral(area)
# Usa el ID del objeto como clave
object_id = int(x1) + int(y1) + int(x2) + int(y2)
if object_id in previous_positions:
prev_positions = previous_positions[object_id]
if len(prev_positions) >= 1:
prev_cx, prev_cy = prev_positions[-1]
# Calcula la distancia euclidiana entre las posiciones
actuales y previas
distance = np.sqrt((cx - prev_cx) ** 2 + (cy - prev_cy)
** 2)
# Normaliza la distancia por el área del bounding box
normalized_speed = (distance / area) * 100 #
Multiplicar por 100
speeds[object_id] = normalized_speed
all_speeds.append(normalized_speed)
# Añadir la velocidad a la ventana de tiempo
state_windows[object_id].append(normalized_speed)
if len(state_windows[object_id]) > 5: # Ajustar la
longitud de la ventana según sea necesario
state_windows[object_id].popleft()
# Almacenar la posición actual
current_positions[object_id] = (cx, cy)
previous_positions[object_id].append((cx, cy))
# Mantener las últimas 30 posiciones
if len(previous_positions[object_id]) > 30:
previous_positions[object_id].popleft()
# Dibuja las detecciones en el frame
for i in range(len(boxes)):
x1, y1, x2, y2 = boxes[i]
conf = confs[i]
cls = clss[i]
if names[int(cls)] == "person" and conf > 0.5:
# Dibuja la caja delimitadora alrededor de la persona detectada
cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), (int(y2))), (
0, 255, 0), 1)
object_id = int(x1) + int(y1) + int(x2) + int(y2)
if object_id in speeds:
# Determinar el estado basado en las velocidades de la
ventana de tiempo
state = determinar_estado(state_windows[object_id],
stopping_threshold, running_threshold)
# Muestra el estado en la parte superior de la caja
delimitadora
cv2.putText(frame, state, (int(x1), int(y1) - 10), cv2.
FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
# Mostrar el frame procesado
cv2.imshow('Frame', frame)
# Salir del bucle si se presiona la tecla 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Escribir el frame en el archivo de video (comentado)
# video_writer.write(frame)
# Calcular estadísticas de velocidad
if all_speeds:
min_speed = min(all_speeds)
max_speed = max(all_speeds)
avg_speed = mean(all_speeds)
try:
mode_speed = mode(all_speeds)
except StatisticsError:
mode_speed = "No unique mode"
print(f"Minimum Speed: {min_speed:.5f} px/area")
print(f"Maximum Speed: {max_speed:.5f} px/area")
print(f"Average Speed: {avg_speed:.5f} px/area")
print(f"Mode Speed: {mode_speed if isinstance(mode_speed, str) else
mode_speed:.5f} px/area")
# Liberar el objeto de captura de video y cerrar ventanas
cap.release()
# video_writer.release()
cv2.destroyAllWindows()
El mié, 10 jul 2024 a la(s) 9:28 p.m., Glenn Jocher (
***@***.***) escribió:
… Hello @roscha10 <https://github.com/roscha10>,
Thank you for your kind words! 😊
To address your query about detecting lines anywhere on the screen and
ensuring that the speed estimation remains unaffected by the object's
distance from the camera, you can indeed achieve this with some
adjustments. Here’s a more flexible approach:
1. *Dynamic Region Points*: Instead of fixed region points, you can
dynamically adjust the region points based on the object's position in the
frame.
2. *Perspective Transformation*: Apply a perspective transformation to
account for the varying distances of objects from the camera.
Here’s an updated example to get you started:
import cv2from ultralytics import YOLO, solutions
# Load the YOLOv8 modelmodel = YOLO("yolov8n.pt")names = model.model.names
# Open the video filecap = cv2.VideoCapture("path/to/video/file.mp4")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 writervideo_writer = cv2.VideoWriter("speed_estimation.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
# Initialize SpeedEstimator with dynamic region pointsspeed_obj = solutions.SpeedEstimator(
reg_pts=[(0, 360), (1280, 360)], # Example points, adjust as needed
names=names,
view_img=True,
)
while cap.isOpened():
success, im0 = cap.read()
if not success:
print("Video frame is empty or video processing has been successfully completed.")
break
# Track objects in the frame
tracks = model.track(im0, persist=True, show=False)
# Estimate speed with dynamic region points
im0 = speed_obj.estimate_speed(im0, tracks)
video_writer.write(im0)
cap.release()video_writer.release()cv2.destroyAllWindows()
Key Adjustments:
- *Dynamic Region Points*: Adjust reg_pts dynamically based on object
positions.
- *Perspective Transformation*: Apply transformations to normalize
distances.
For more detailed guidance, you can refer to our Speed Estimation Guide
<https://docs.ultralytics.com/guides/speed-estimation/>.
Feel free to reach out if you have any further questions or need
additional assistance!
—
Reply to this email directly, view it on GitHub
<#8975 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A7E5FJOTH3H7MEBSSLFNP73ZLXNTXAVCNFSM6AAAAABEYVIZNWVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTAMBRGU3DOMA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***
com>
|
Beta Was this translation helpful? Give feedback.
-
es/guides/speed-estimation/
Estimación de la velocidad mediante Ultralytics YOLOv8
https://docs.ultralytics.com/es/guides/speed-estimation/
Beta Was this translation helpful? Give feedback.
All reactions