Skip to content

Commit c5e1211

Browse files
committed
Move FpsMonitor from utils to video module
This commit relocates the FpsMonitor class from the utils module to the video module.
1 parent c5c37e4 commit c5e1211

6 files changed

Lines changed: 64 additions & 44 deletions

File tree

docs/utils/fps.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

docs/utils/video.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66

77
:::supervision.utils.video.VideoSink
88

9+
## FPSMonitor
10+
11+
:::supervision.utils.video.FPSMonitor
12+
913
## get_video_frames_generator
1014

1115
:::supervision.utils.video.get_video_frames_generator
1216

1317
## process_video
1418

1519
:::supervision.utils.video.process_video
20+
21+

mkdocs.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ nav:
4949
- Image: utils/image.md
5050
- Notebook: utils/notebook.md
5151
- File: utils/file.md
52-
- FPS: utils/fps.md
5352
- Changelog: changelog.md
5453

5554
theme:

supervision/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@
4444
from supervision.metrics.detection import ConfusionMatrix, MeanAveragePrecision
4545
from supervision.tracker.byte_tracker.core import ByteTrack
4646
from supervision.utils.file import list_files_with_extensions
47-
from supervision.utils.fps import FpsMonitor
4847
from supervision.utils.image import ImageSink, crop_image
4948
from supervision.utils.notebook import plot_image, plot_images_grid
5049
from supervision.utils.video import (
5150
VideoInfo,
5251
VideoSink,
5352
get_video_frames_generator,
5453
process_video,
54+
FPSMonitor
5555
)

supervision/utils/fps.py

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1 @@
1-
import time
2-
from collections import deque
31

4-
5-
class FpsMonitor:
6-
def __init__(self, sample_size: int = 30):
7-
"""
8-
Initialize class to measure Frame per second for latency benchmark.
9-
Args:
10-
sample_size (int): Maximum observation to measure latency benchmark
11-
Examples:
12-
```python
13-
>>> import supervision as sv
14-
15-
>>> fps_monitor = sv.FpsMonitor()
16-
>>> while True:
17-
... (...)
18-
... fps_monitor.tick()
19-
... fps = fps_monitor()
20-
```
21-
"""
22-
self.all_timestamps = deque(maxlen=sample_size)
23-
24-
def __call__(self) -> float:
25-
if not self.all_timestamps:
26-
return 0.0
27-
taken_time = self.all_timestamps[-1] - self.all_timestamps[0]
28-
return (len(self.all_timestamps)) / taken_time if taken_time != 0 else 0.0
29-
30-
def tick(self) -> None:
31-
self.all_timestamps.append(time.monotonic())
32-
33-
def reset(self) -> None:
34-
self.all_timestamps.clear()

supervision/utils/video.py

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import time
4+
from collections import deque
35
from dataclasses import dataclass
46
from typing import Callable, Generator, Optional, Tuple
57

@@ -71,13 +73,11 @@ class VideoSink:
7173
```python
7274
>>> import supervision as sv
7375
74-
>>> video_info = sv.VideoInfo.from_video_path(video_path='source_video.mp4')
76+
>>> video_info = sv.VideoInfo.from_video_path('source.mp4')
77+
>>> frames_generator = get_video_frames_generator('source.mp4')
7578
76-
>>> with sv.VideoSink(target_path='target_video.mp4',
77-
... video_info=video_info,
78-
codec='H264') as sink:
79-
... for frame in get_video_frames_generator(source_path='source_video.mp4',
80-
... stride=2):
79+
>>> with sv.VideoSink(target_path='target.mp4', video_info=video_info) as sink:
80+
... for frame in frames_generator:
8181
... sink.write_frame(frame=frame)
8282
```
8383
"""
@@ -202,3 +202,54 @@ def process_video(
202202
):
203203
result_frame = callback(frame, index)
204204
sink.write_frame(frame=result_frame)
205+
206+
207+
class FPSMonitor:
208+
"""
209+
A class for monitoring frames per second (FPS) to benchmark latency.
210+
"""
211+
def __init__(self, sample_size: int = 30):
212+
"""
213+
Args:
214+
sample_size (int): The maximum number of observations for latency
215+
benchmarking.
216+
217+
Examples:
218+
```python
219+
>>> import supervision as sv
220+
221+
>>> frames_generator = sv.get_video_frames_generator('source.mp4')
222+
>>> fps_monitor = sv.FPSMonitor()
223+
224+
>>> for frame in frames_generator:
225+
... # your processing code here
226+
... fps_monitor.tick()
227+
... fps = fps_monitor()
228+
```
229+
"""
230+
self.all_timestamps = deque(maxlen=sample_size)
231+
232+
def __call__(self) -> float:
233+
"""
234+
Computes and returns the average FPS based on the stored time stamps.
235+
236+
Returns:
237+
float: The average FPS. Returns 0.0 if no time stamps are stored.
238+
"""
239+
240+
if not self.all_timestamps:
241+
return 0.0
242+
taken_time = self.all_timestamps[-1] - self.all_timestamps[0]
243+
return (len(self.all_timestamps)) / taken_time if taken_time != 0 else 0.0
244+
245+
def tick(self) -> None:
246+
"""
247+
Adds a new time stamp to the deque for FPS calculation.
248+
"""
249+
self.all_timestamps.append(time.monotonic())
250+
251+
def reset(self) -> None:
252+
"""
253+
Clears all the time stamps from the deque.
254+
"""
255+
self.all_timestamps.clear()

0 commit comments

Comments
 (0)