Ex: Edit a Recording

Filter or modify a recording’s points and save the result with Python.

This example edits a Voyant recording and saves it back: read each frame, filter or modify its points as a numpy matrix, rebuild the frame with with_points(), and record the result to a new .vynt file. The input file is read-only throughout — the edits land in a new file.

The same flow works on live frames from a CarbonClient: filter or annotate each frame as it arrives, then record it.

Requires pip install voyant-api.

What You’ll Learn

  • How to chain VoyantPlayback into VoyantRecorder to rewrite a recording
  • How to edit the points() matrix and rebuild a frame with with_points()
  • How to stamp the user-owned per-point column (user_data)

Prerequisites

Example Code

View the complete example on GitHub: edit_recording_example.py

Key Concepts

Reader and Writer

Playback is the reader and the recorder is the writer. With keep_invalid_points left False, invalid returns are dropped as frames are read, so the output holds only valid points:

from voyant_api import RecordStatus, VoyantFrame, VoyantPlayback, VoyantRecorder, init_voyant_logging

init_voyant_logging()

COLS = VoyantFrame.points_columns()

playback = VoyantPlayback(keep_invalid_points=False)
playback.open("recording.vynt")

Editing the Points Matrix

frame.points() is a numpy matrix with one column per recorded field — COLS gives the column order. Any numpy edit works. This one keeps points within a range limit and stamps the user-owned column to mark the rows the script touched — the visualizer’s User Data color mode can then highlight them:

matrix = frame.points()

keep = matrix[:, COLS.index("range_m")] <= max_range
matrix = matrix[keep]
matrix[:, COLS.index("user_data")] = 1

Points that arrive as x/y/z — from a ROS cloud, a CSV — go in with cartesian=True, which the library projects back into the stored spherical geometry. Pass the same cartesian to points() and with_points(): a basis mismatch is not detectable, so a Cartesian matrix passed without the flag stores x, y, z into the range and angle fields.

Working from a pandas DataFrame instead? Select columns by name so column order can’t drift: matrix = df[VoyantFrame.points_columns()].to_numpy().

Rebuilding and Recording the Frame

with_points() returns a new frame that keeps everything else from the frame it came from — state snapshots, timestamps, frame index, device identity — so the output recording plays back like the input with only its points changed:

with VoyantRecorder("edited.vynt", timestamp_filename=False) as recorder:
    for frame in playback:
        if frame is None:
            break

        # ... edit `matrix` as above ...

        edited = frame.with_points(matrix)
        if recorder.record_frame(edited) == RecordStatus.STOP:
            break

Command Line Options

python edit_recording_example.py --input recording.vynt --output edited.vynt

# Custom range limit in meters
python edit_recording_example.py --input recording.vynt --output edited.vynt --max-range 25

Expected Output

frame 133: kept 14208/15850 points
frame 134: kept 14197/15873 points
...

Next Steps


Copyright © Voyant Photonics, Inc.

This site uses Just the Docs, a documentation theme for Jekyll.