Converting PCAPs to Other Formats

PCAPs to CSV

Sometimes we want to get a point cloud (XYZ + other fields) as a CSV file for further analysis with other tools.

To convert the first 5 scans of our sample data from a pcap file, you can try:

$ python3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH $SAMPLE_DATA_JSON_PATH pcap-to-csv --scan-num 5

The source code of an example below:

 1from itertools import islice
 2# precompute xyzlut to save computation in a loop
 3xyzlut = client.XYZLut(metadata)
 4
 5# create an iterator of LidarScans from pcap and bound it if num is specified
 6scans = iter(client.Scans(source))
 7# if num_scans is None
 8scans = islice(scans, start_index, start_index + num_scans)
 9
10row_layer = np.fromfunction(lambda i, j: i,
11        (metadata.format.pixels_per_column,
12            metadata.format.columns_per_frame), dtype=int)
13column_layer = np.fromfunction(lambda i, j: j,
14        (metadata.format.pixels_per_column,
15            metadata.format.columns_per_frame), dtype=int)
16column_layer_staggered = client.destagger(metadata, column_layer,
17        inverse=True)
18
19idx = None
20for idx, scan in enumerate(scans):
21
22    # initialize the field names for csv header
23    if not field_names or not field_fmts:
24        field_names, field_fmts = get_fields_info(scan)
25
26    # copy per-column timestamps and measurement_ids for each beam
27    timestamps = np.tile(scan.timestamp, (scan.h, 1))
28    measurement_ids = np.tile(scan.measurement_id, (scan.h, 1))
29
30    # grab channel data
31    fields_values = [scan.field(ch) for ch in scan.fields]
32
33    frame = np.dstack((timestamps, row_layer, column_layer_staggered,
34        measurement_ids, *fields_values))
35
36    # output points in "image" vs. staggered order
37    frame = client.destagger(metadata, frame)
38
39    # destagger XYZ separately since it has a different type
40    xyz = xyzlut(scan.field(client.ChanField.RANGE))
41    xyz_destaggered = client.destagger(metadata, xyz)
42
43    if dual:
44        xyz2 = xyzlut(scan.field(client.ChanField.RANGE2))
45        xyz2_destaggered = client.destagger(metadata, xyz2)
46
47        # get all data as one H x W x num fields int64 array for savetxt()
48        frame = np.dstack(tuple(map(lambda x: x.astype(object),
49            (frame, xyz_destaggered, xyz2_destaggered))))
50
51    else:
52        # get all data as one H x W x num fields int64 array for savetxt()
53        frame = np.dstack(tuple(map(lambda x: x.astype(object),
54            (frame, xyz_destaggered))))
55
56    frame_colmajor = np.swapaxes(frame, 0, 1)
57
58    # write csv out to file
59    csv_path = output_names[idx]
60    print(f'write frame index #{idx + start_index}, to file: {csv_path}')
61
62    header = '\n'.join([f'frame num: {idx}', field_names])
63
64    np.savetxt(csv_path,
65               frame_colmajor.reshape(-1, frame.shape[2]),
66               fmt=field_fmts,
67               delimiter=',',
68               header=header)

Because we stored the scan as structured 2D images, we can easily recover it by loading it back into a numpy.ndarray and continuing to use it as a 2D image.

import numpy as np

# read array from CSV
frame = np.loadtxt('my_frame_00000.csv', delimiter=',')

# convert back to "fat" 2D image [H x W x num_fields] shape
frame = frame.reshape((128, -1, frame.shape[1]))

We used 128 while restoring 2D image from a CSV file because it’s the number of channels of our OS-1-128.pcap sample data recording.

PCAPs to LAS

To convert to the first 5 scans of our sample data from a pcap file to LAS, you can try:

$ python3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH $SAMPLE_DATA_JSON_PATH pcap-to-las --scan-num 5

Checkout the examples.pcap.pcap_to_las() documentation for the example source code.

PCAPs to PCD

To convert to the first 5 scans of our sample data from a pcap file to PCD, you can try:

$ python3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH $SAMPLE_DATA_JSON_PATH pcap-to-pcd --scan-num 5

Checkout the examples.pcap.pcap_to_pcd() documentation for the example source code.

PCAPs to PLY

Here we will reuse the PCAP to PCD function that uses Open3d and will exploit the extensive Open3d File IO that gives us an easy way to save the loaded point cloud to PLY. Alternative ways are available via plyfile library.

To convert to the first 5 scans of our sample data from a pcap file to PLY, you can try:

$ python3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH $SAMPLE_DATA_JSON_PATH pcap-to-ply --scan-num 5

Checkout the examples.pcap.pcap_to_ply() documentation for the example source code.