Skip to content

AnimationStream

py3r.behaviour.animation.animation_stream.AnimationStream

AnimationStream(
    *,
    points_xy: ndarray,
    point_names: list[str],
    draw_point_indices: list[int],
    frame_ids: ndarray,
    lines_idx: list[tuple[int, int]],
    line_keys: list[tuple[str, str]],
    boundary_arrays: list[tuple[str, ndarray]],
    text_overlays: list[tuple[str, ndarray | None]] | None,
    canvas_size: tuple[int, int],
    fps: float,
    bg_color: tuple[int, int, int],
    style: dict | None,
    style_sources: dict[str, ndarray] | None,
    pixel_coords: bool,
    bounds_pad: float = 0.05,
)

OpenCV-backed frame stream for points, lines, and boundaries.

Construct this class through Tracking.animation_stream and Features.animation_stream. Frames are generated lazily on demand, supporting both random-access rendering (get_frame(i)) and sequential playback (read(), iteration, play(), save()).

frame_count property

frame_count: int

Number of renderable frames.

frame_ids property

frame_ids: ndarray

Copy of source frame identifiers aligned to stream indices.

reset

reset() -> None

Reset the internal sequential cursor.

Examples:

>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> with data_path("py3r.behaviour.tracking._data", "dlc_single.csv") as p:
...     t = Tracking.from_dlc(str(p), handle="ex", fps=30)
>>> s = t.animation_stream(points=["p1"], pixel_coords=True, canvas_size=(64, 48))
>>> _ = s.read()
>>> s.reset()
>>> ok, _ = s.read()
>>> ok
True

read

read() -> tuple[bool, np.ndarray | None]

Return the next rendered frame using VideoCapture-style semantics.

Returns:

Type Description
bool

tuple[bool, np.ndarray | None]: (True, frame) while frames remain;

ndarray | None

otherwise (False, None).

Examples:

>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> with data_path("py3r.behaviour.tracking._data", "dlc_single.csv") as p:
...     t = Tracking.from_dlc(str(p), handle="ex", fps=30)
>>> s = t.animation_stream(points=["p1"], pixel_coords=True, canvas_size=(64, 48))
>>> ok, frame = s.read()
>>> ok and frame is not None
True

get_frame

get_frame(frame_idx: int) -> np.ndarray

Render and return one frame by stream index.

Parameters:

Name Type Description Default

frame_idx

int

Zero-based frame index.

required

Returns:

Type Description
ndarray

np.ndarray: Rendered BGR image with shape (H, W, 3).

Raises:

Type Description
IndexError

If frame_idx is out of range.

Examples:

>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> with data_path("py3r.behaviour.tracking._data", "dlc_single.csv") as p:
...     t = Tracking.from_dlc(str(p), handle="ex", fps=30)
>>> s = t.animation_stream(points=["p1"], pixel_coords=True, canvas_size=(64, 48))
>>> frame0 = s.get_frame(0)
>>> frame0.ndim
3

render_into

render_into(
    frame: ndarray, *, frame_idx: int, copy: bool = True
) -> np.ndarray

Draw stream geometry into an existing frame buffer.

Parameters:

Name Type Description Default

frame

ndarray

Base BGR image buffer with shape (H, W, 3).

required

frame_idx

int

Stream frame index to render.

required

copy

bool

If True, draw into a copy. If False, draw in-place.

True

Returns:

Type Description
ndarray

np.ndarray: Rendered frame buffer.

Raises:

Type Description
IndexError

If frame_idx is out of range.

ValueError

If frame does not have shape (H, W, 3).

Examples:

>>> import numpy as np
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> with data_path("py3r.behaviour.tracking._data", "dlc_single.csv") as p:
...     t = Tracking.from_dlc(str(p), handle="ex", fps=30)
>>> s = t.animation_stream(points=["p1"], pixel_coords=True, canvas_size=(32, 24))
>>> base = np.zeros((24, 32, 3), dtype=np.uint8)
>>> out = s.render_into(base, frame_idx=0, copy=True)
>>> out.shape
(24, 32, 3)

play

play(
    *,
    fps: float | None = None,
    frame_step: int = 1,
    speed: float = 1.0,
    window_name: str = "geometry_animation",
    loop: bool = False,
    video_path: str | None = None,
    align_to_frame_ids: bool = True,
) -> None

Play stream in an OpenCV window.

Press q or Esc to exit playback.

Parameters:

Name Type Description Default

fps

float | None

Playback FPS. Uses stream FPS when None.

None

frame_step

int

Number of stream frames to advance per displayed frame.

1

speed

float

Playback speed multiplier.

1.0

window_name

str

OpenCV window name.

'geometry_animation'

loop

bool

If True, restart at the end.

False

video_path

str | None

Optional source video to draw overlays on.

None

align_to_frame_ids

bool

If True, seek source video to first frame_id.

True

Raises:

Type Description
ValueError

If frame_step < 1 or speed <= 0.

Examples:

>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> with data_path("py3r.behaviour.tracking._data", "dlc_single.csv") as p:
...     t = Tracking.from_dlc(str(p), handle="ex", fps=30)
>>> s = t.animation_stream(points=["p1"], pixel_coords=True, canvas_size=(64, 48))
>>> s.play(loop=False, speed=1.0)  # xdoctest: +SKIP

save

save(
    out_path: str,
    *,
    fps: float | None = None,
    frame_step: int = 1,
    video_path: str | None = None,
    align_to_frame_ids: bool = True,
    codec: str = "mp4v",
) -> None

Render stream to a video file.

If video_path is provided, geometry is composited onto decoded frames.

Parameters:

Name Type Description Default

out_path

str

Output video path.

required

fps

float | None

Output FPS when rendering without video_path.

None

frame_step

int

Number of stream frames to skip per output frame.

1

video_path

str | None

Optional source video to draw overlays on.

None

align_to_frame_ids

bool

If True, seek source video to first frame_id.

True

codec

str

FourCC codec string (for example "mp4v").

'mp4v'

Raises:

Type Description
ValueError

If frame_step < 1 or writer/capture cannot be opened.

Examples:

>>> import tempfile
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> with data_path("py3r.behaviour.tracking._data", "dlc_single.csv") as p:
...     t = Tracking.from_dlc(str(p), handle="ex", fps=30)
>>> s = t.animation_stream(points=["p1"], pixel_coords=True, canvas_size=(64, 48))
>>> with tempfile.NamedTemporaryFile(suffix=".mp4") as f:
...     s.save(f.name)  # xdoctest: +SKIP