OSF Python Examples
Ouster Python API for OSF
Python OSF Reader/Writer API is a Python binding to the C++
OSF Reader/Writer implementation
which means that all reading and writing operations works at native speeds.
All examples below assume that a user has an osf_file
variable with a path to an OSF file and
ouster.osf
package is imported:
import ouster.osf as osf
osf_file = 'path/to/osf_file.osf'
You can use ouster-cli source .... save
commands to generate a test OSF file to test any of the examples.
Every example is wrapped into a CLI and available for quick tests by running
python3 -m ouster.sdk.examples.osf <OSF_FILE.osf> <EXAMPLE_NAME>
:
$ python3 -m ouster.sdk.examples.osf --help
usage: osf.py [-h] [--scan-num SCAN_NUM] OSF EXAMPLE
Ouster Python SDK OSF examples. The EXAMPLE must be one of:
read-scans
slice-scans
get-sensors-info
For example to execute the read-scans
example you can run:
$ python3 -m ouster.sdk.examples.osf <OSF_FILE.osf> read-scans
Read Lidar Scans with osf.Scans
osf.Scans()
interface is the simplest way to get all LidarScan
objects for the first sensor
that was found in an OSF (majority of our test data uses only a single sensor recordings):
scans = osf.OsfScanSource(osf_file).single_source(0)
for scan in scans:
print(f'scan = {scan}, WxH={scan.w}x{scan.h}')
Underneath it looks for available sensor streams, peeks first, creates the osf.Reader
, reads the
messages and decodes them to LidarScan
objects.
Get Sensors Info with osf.Reader
osf.Reader
is the base Reader
interface that get info about start/end_ts
, reads and
decodes all metadata entries, get access to chunks and messages of the OSF file.
Sensors information is stored as osf.LidarSensor
metadata entry and can be read with the
reader.meta_store.find()
function that returns all metadata entry of the specified type (in our
case it’s of type osf.LidarSensor
):
scans = osf.OsfScanSource(osf_file)
for sensor_id, info in enumerate(scans.metadata):
print(f"sensor[{sensor_id}] = ", info)
Write Lidar Scan with sliced fields with osf.Writer
We will look into the osf.Writer
example on the task of re-coding the available OSF file into Lidar
Scans with a reduced fields. By reduce fields we mean here that if LidarScan has 7
channel
fields, we can keep only 3
and save the disk space and bandwidth during replay.
A general scheme of writing scans to the OSF with Writer:
Create
osf.Writer
with the output file name, lidar metadata(s) (ouster.sdk.client.SensorInfo
) and optionally the desired output scan fields.Use the writer’s
save
functionwriter.save(index, scan)
to encode the LidarScanscan
into the underlying message buffer for lidarindex
and finally push it to disk. If you have multiple lidar sensors you can save the scans simultaneously by providing them in an array towriter.save
.
# Scans reader from input OSF
scans = osf.OsfScanSource(osf_file).single_source(0)
# New field types should be a subset of fields in encoded LidarScan so we just assume that
# RANGE, SIGNAL and REFLECTIVITY fields will be present in the input OSF file.
fields_to_write = [client.ChanField.RANGE, client.ChanField.SIGNAL, client.ChanField.REFLECTIVITY]
output_file_base = os.path.splitext(os.path.basename(osf_file))[0]
output_file = output_file_base + '_sliced.osf'
# Create Writer with a subset of fields to save (i.e. slicing will happen
# automatically on write)
writer = osf.Writer(output_file, scans.metadata, fields_to_write)
# Read scans and write back
for scan in scans:
print(f"writing sliced scan with ts = {scan.get_first_valid_packet_timestamp()}")
writer.save(0, scan)
writer.close()