The LidarFrame Representation¶
The core.LidarFrame class is explained in depth in the LidarFrame, which we recommend reading.
We provide example code to aid in understanding.
Query frame for available fields¶
To run the sample code which queries fields from a frame, use the pcap.pcap_query_frame() example:
$ python3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH query-frame
PS > py -3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH query-frame
You can run the above on pcaps containing packets of any type of core.UDPProfileLidar.
You might notice that on a pcap containing dual returns data, you should note
that your dtypes will not be consistently uint32_t, as you can tell
from the result of running query-frame on dual returns data:
Available fields and corresponding dtype in LidarFrame
RANGE uint32
RANGE2 uint32
SIGNAL uint16
SIGNAL2 uint16
REFLECTIVITY uint8
REFLECTIVITY2 uint8
NEAR_IR uint16
Projecting into Cartesian Coordinates¶
Let’s plot some points!
If you have a configured sensor, you can plot some points in XYZ using the plot-xyz-points() example:
$ python3 -m ouster.sdk.examples.core $SENSOR_HOSTNAME plot-xyz-points
PS > py -3 -m ouster.sdk.examples.core $SENSOR_HOSTNAME plot-xyz-points
That should open a 3D plot of a single frame of your location taken just now by your sensor. You should be able to recognize the contours of the scene around you.
If you don’t have a sensor, you can run the same code with our
pcap.pcap_display_xyz_points() pcap example:
$ python3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH plot-xyz-points --frame-num 84
PS > py -3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH plot-xyz-points --frame-num 84
For visualizers which will stream consecutive frames from sensors or pcaps, check out our utilities in Visualizations in 3D.
Working with 2D and 3D Representations Simultaneously¶
The direct correlation between 2D and 3D representations in an Ouster sensor provides a powerful framework for working with the data. As an easy example, you might decide you want to look at only the 3D points within a certain range and from certain azimuth angles.
# 3. Slicing: Limit to the first azimuth_fraction
col_limit = math.floor(info.format.columns_per_frame * azimuth_fraction)
# Standard NumPy slicing [row, col, channel]
xyz_filtered = xyz_filtered[:, 0:col_limit, :]
Since we’d like to filter on azimuth angles, first we first destagger both the 2D and 3D points, so
that our columns in the HxW representation correspond to azimuth angle, not timestamp. (See
2D Data Layout: Staggered vs. Destaggered for an explanation on destaggering.)
Then we filter the 3D points xyz_destaggered by comparing the range measurement to
range_min, which we can do because there is a 1:1 correspondence between the columns and rows of
the destaggered representations of xyz_destaggered and range_destaggered. (Similarly, there
would be a 1:1 correspondence between the staggered representations xyz and range, where the
columns correspond with timestamp).
Finally, we select only the azimuth columns we’re interested in. In this case, we’ve arbitrarily chosen the first 270 degrees of rotation.
If you have a configured sensor, you can run this code with an example:
$ python3 -m ouster.sdk.examples.core $SENSOR_HOSTNAME filter-3d-by-range-and-azimuth
PS > py -3 -m ouster.sdk.examples.core $SENSOR_HOSTNAME filter-3d-by-range-and-azimuth