The LidarScan Representation
We provide example code to aid in understanding.
To run the sample code which queries fields from a scan, use the
$ python3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH $SAMPLE_DATA_JSON_PATH query-scan
PS > py -3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH $SAMPLE_DATA_JSON_PATH query-scan
You can run the above on pcaps containing packets of any type of
You might notice that on a pcap containing dual returns data, you should note
dtypes will not be consistently
uint32_t, as you can tell
from the result of running
query-scan on dual returns data:
Available fields and corresponding dtype in LidarScan RANGE uint32 RANGE2 uint32 SIGNAL uint16 SIGNAL2 uint16 REFLECTIVITY uint8 REFLECTIVITY2 uint8 NEAR_IR uint16
To generate staggered and destaggered images yourself, you can try the following sample code:
import matplotlib.pyplot as plt from more_itertools import nth # ... `metadata` and `source` variables created as in the previous examples scans = client.Scans(source) # iterate `scans` and get the 84th LidarScan (it can be different with your data) scan = nth(scans, 84) ranges = scan.field(client.ChanField.RANGE) # destagger ranges, notice `metadata` use, that is needed to get # sensor intrinsics and correctly data transforms ranges_destaggered = client.destagger(source.metadata, ranges) plt.imshow(ranges_destaggered, cmap='gray', resample=False)
Let’s plot some points!
$ python3 -m ouster.sdk.examples.client $SENSOR_HOSTNAME plot-xyz-points
PS > py -3 -m ouster.sdk.examples.client $SENSOR_HOSTNAME plot-xyz-points
That should open a 3D plot of a single scan 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 $SAMPLE_DATA_JSON_PATH plot-xyz-points --scan-num 84
PS > py -3 -m ouster.sdk.examples.pcap $SAMPLE_DATA_PCAP_PATH $SAMPLE_DATA_JSON_PATH plot-xyz-points --scan-num 84
For visualizers which will stream consecutive frames from sensors or pcaps, check out our utilities in Visualizations in 3D.
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.
1# obtain destaggered range 2range_destaggered = client.destagger(metadata, 3 scan.field(client.ChanField.RANGE)) 4 5# obtain destaggered xyz representation 6xyzlut = client.XYZLut(metadata) 7xyz_destaggered = client.destagger(metadata, xyzlut(scan)) 8 9# select only points with more than min range using the range data 10xyz_filtered = xyz_destaggered * (range_destaggered[:, :, np.newaxis] > 11 (range_min * 1000)) 12 13# get first 3/4 of scan 14to_col = math.floor(metadata.mode.cols * 3 / 4) 15xyz_filtered = xyz_filtered[:, 0:to_col, :]
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
Staggered vs Destaggered 2D Representations 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
range_destaggered. (Similarly, there
would be a 1:1 correspondence between the staggered representations
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.client $SENSOR_HOSTNAME filter-3d-by-range-and-azimuth
PS > py -3 -m ouster.sdk.examples.client $SENSOR_HOSTNAME filter-3d-by-range-and-azimuth