def test_scan_viz_extras(meta: client.SensorInfo, scan: client.LidarScan) -> None: """Check rendering of labels, cuboids, clouds and images together.""" point_viz = viz.PointViz("Test Viz") ls_viz = viz.LidarScanViz(meta, point_viz) cube1 = viz.Cuboid(np.identity(4), (1.0, 0, 0)) # scaled in y and translated in x pose2 = np.array([ [1, 0, 0, 5], [0, 2, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], ]) cube2 = viz.Cuboid(pose2, (0, 1, 0, 0.5)) label1 = viz.Label("Baz\nQux", 0.0, 0.0, 2.0) point_viz.add(label1) point_viz.add(cube1) point_viz.add(cube2) ls_viz.scan = scan point_viz.camera.dolly(150) ls_viz.draw() point_viz.run()
def test_scan_viz_smoke(meta: client.SensorInfo, scan: client.LidarScan) -> None: """Smoke test LidarScan visualization.""" ls_viz = viz.LidarScanViz(meta) ls_viz.scan = scan ls_viz.draw() ls_viz.run()
def test_scan_viz_destruction(meta: client.SensorInfo, point_viz: viz.PointViz) -> None: """Check that LidarScan is destroyed deterministically.""" ls_viz = viz.LidarScanViz(meta, point_viz) ref = weakref.ref(ls_viz) del ls_viz assert ref() is None
def test_viz_multiple_instances(meta: client.SensorInfo, scan: client.LidarScan) -> None: """Check that destructing a visualizer doesn't break other instances.""" point_viz = viz.PointViz("Test Viz") # will call destructor, make sure it doesn't do anything silly like terminate glfw point_viz2 = viz.PointViz("Test Viz2") del point_viz2 ls_viz = viz.LidarScanViz(meta, point_viz) ls_viz.scan = scan ls_viz.draw() point_viz.run()
- ideally, run() would open/close window - auto camera movement example? """ from ouster import client, pcap from ouster.sdk import viz meta_path = "/mnt/aux/test_drives/OS1_128_2048x10.json" pcap_path = "/mnt/aux/test_drives/OS1_128_2048x10.pcap" meta = client.SensorInfo(open(meta_path).read()) packets = pcap.Pcap(pcap_path, meta) scans = iter(client.Scans(packets)) point_viz = viz.PointViz("Example Viz") ls_viz = viz.LidarScanViz(meta, point_viz) ls_viz.scan = next(scans) ls_viz.draw() print("Showing first frame, close visuzlier window to continue") point_viz.run() ls_viz.scan = next(scans) ls_viz.draw() print("Showing second frame, close visuzlier window to continue") point_viz.run() # won't work on macos, but convenient: # import threading # render_thread = threading.Thread(target=point_viz.run) # render_thread.start()
def main(): """PointViz visualizer examples.""" parser = argparse.ArgumentParser( description=main.__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('pcap_path', nargs='?', metavar='PCAP', help='path to pcap file') parser.add_argument('meta_path', nargs='?', metavar='METADATA', help='path to metadata json') args = parser.parse_args() pcap_path = os.getenv("SAMPLE_DATA_PCAP_PATH", args.pcap_path) meta_path = os.getenv("SAMPLE_DATA_JSON_PATH", args.meta_path) if not pcap_path or not meta_path: print("ERROR: Please add SAMPLE_DATA_PCAP_PATH and SAMPLE_DATA_JSON_PATH to" + " environment variables or pass <pcap_path> and <meta_path>") sys.exit() print(f"Using:\n\tjson: {meta_path}\n\tpcap: {pcap_path}") # Getting data sources meta = client.SensorInfo(open(meta_path).read()) packets = pcap.Pcap(pcap_path, meta) scans = iter(client.Scans(packets)) # ============================== print("Ex 0: Empty Point Viz") # [doc-stag-empty-pointviz] # Creating a point viz instance point_viz = viz.PointViz("Example Viz") viz.add_default_controls(point_viz) # ... add objects here # update internal objects buffers and run visualizer point_viz.update() point_viz.run() # [doc-etag-empty-pointviz] # ========================================================================= print("Ex 1.0:\tImages and Labels: the Image object and 2D Image set_position() - height-normalized screen coordinates") label_top = viz.Label("[0, 1]", 0.5, 0.0, align_top=True) label_top.set_scale(2) point_viz.add(label_top) label_bot = viz.Label("[0, -1]", 0.5, 1, align_top=False) label_bot.set_scale(2) point_viz.add(label_bot) # [doc-stag-image-pos-center] img = viz.Image() img.set_image(np.full((10, 10), 0.5)) img.set_position(-0.5, 0.5, -0.5, 0.5) point_viz.add(img) # [doc-etag-image-pos-center] # visualize point_viz.update() point_viz.run() # ========================================================================= print("Ex 1.1:\tImages and Labels: Window-aligned images with 2D Image set_hshift() - width-normalized [-1, 1] horizontal shift") # [doc-stag-image-pos-left] # move img to the left img.set_position(0, 1, -0.5, 0.5) img.set_hshift(-1) # [doc-etag-image-pos-left] # visualize point_viz.update() point_viz.run() # [doc-stag-image-pos-right] # move img to the right img.set_position(-1, 0, -0.5, 0.5) img.set_hshift(1) # [doc-etag-image-pos-right] # visualize point_viz.update() point_viz.run() # [doc-stag-image-pos-right-bottom] # move img to the right bottom img.set_position(-1, 0, -1, 0) img.set_hshift(1) # [doc-etag-image-pos-right-bottom] # visualize point_viz.update() point_viz.run() # remove_objs(point_viz, [label_top, label_mid, label_bot, img]) remove_objs(point_viz, [label_top, label_bot, img]) # ======================================= print("Ex 1.2:\tImages and Labels: Lidar Scan Fields as Images") # [doc-stag-scan-fields-images] scan = next(scans) img_aspect = (meta.beam_altitude_angles[0] - meta.beam_altitude_angles[-1]) / 360.0 img_screen_height = 0.4 # [0..2] img_screen_len = img_screen_height / img_aspect # prepare field data ranges = scan.field(client.ChanField.RANGE) ranges = client.destagger(meta, ranges) ranges = np.divide(ranges, np.amax(ranges), dtype=np.float32) signal = scan.field(client.ChanField.SIGNAL) signal = client.destagger(meta, signal) signal = np.divide(signal, np.amax(signal), dtype=np.float32) # creating Image viz elements range_img = viz.Image() range_img.set_image(ranges) # top center position range_img.set_position(-img_screen_len / 2, img_screen_len / 2, 1 - img_screen_height, 1) point_viz.add(range_img) signal_img = viz.Image() signal_img.set_image(signal) img_aspect = (meta.beam_altitude_angles[0] - meta.beam_altitude_angles[-1]) / 360.0 img_screen_height = 0.4 # [0..2] img_screen_len = img_screen_height / img_aspect # bottom center position signal_img.set_position(-img_screen_len / 2, img_screen_len / 2, -1, -1 + img_screen_height) point_viz.add(signal_img) # [doc-etag-scan-fields-images] # visualize point_viz.update() point_viz.run() print("Ex 1.3:\tImages and Labels: Adding labels") # [doc-stag-scan-fields-images-labels] range_label = viz.Label(str(client.ChanField.RANGE), 0.5, 0, align_top=True) range_label.set_scale(1) point_viz.add(range_label) signal_label = viz.Label(str(client.ChanField.SIGNAL), 0.5, 1 - img_screen_height / 2, align_top=True) signal_label.set_scale(1) point_viz.add(signal_label) # [doc-etag-scan-fields-images-labels] # visualize point_viz.update() point_viz.run() # =============================================================== print("Ex 2.0:\tPoint Clouds: As Structured Points") # [doc-stag-scan-structured] cloud_scan = viz.Cloud(meta) cloud_scan.set_range(scan.field(client.ChanField.RANGE)) cloud_scan.set_key(signal) point_viz.add(cloud_scan) # [doc-etag-scan-structured] # visualize point_viz.update() point_viz.run() remove_objs(point_viz, [cloud_scan]) # =============================================================== print("Ex 2.1:\tPoint Clouds: As Unstructured Points") # [doc-stag-scan-unstructured] # transform scan data to 3d points xyzlut = client.XYZLut(meta) xyz = xyzlut(scan.field(client.ChanField.RANGE)) cloud_xyz = viz.Cloud(xyz.shape[0] * xyz.shape[1]) cloud_xyz.set_xyz(np.reshape(xyz, (-1, 3))) cloud_xyz.set_key(signal.ravel()) point_viz.add(cloud_xyz) # [doc-etag-scan-unstructured] point_viz.camera.dolly(150) # visualize point_viz.update() point_viz.run() # ======================================================= print("Ex 2.2:\tPoint Clouds: Custom Axes Helper as Unstructured Points") # [doc-stag-axes-helper] # basis vectors x_ = np.array([1, 0, 0]).reshape((-1, 1)) y_ = np.array([0, 1, 0]).reshape((-1, 1)) z_ = np.array([0, 0, 1]).reshape((-1, 1)) axis_n = 100 line = np.linspace(0, 1, axis_n).reshape((1, -1)) # basis vector to point cloud axis_points = np.hstack((x_ @ line, y_ @ line, z_ @ line)).transpose() # colors for basis vectors axis_color_mask = np.vstack(( np.full((axis_n, 4), [1, 0.1, 0.1, 1]), np.full((axis_n, 4), [0.1, 1, 0.1, 1]), np.full((axis_n, 4), [0.1, 0.1, 1, 1]))) cloud_axis = viz.Cloud(axis_points.shape[0]) cloud_axis.set_xyz(axis_points) cloud_axis.set_key(np.full(axis_points.shape[0], 0.5)) cloud_axis.set_mask(axis_color_mask) cloud_axis.set_point_size(3) point_viz.add(cloud_axis) # [doc-etag-axes-helper] point_viz.camera.dolly(50) # visualize point_viz.update() point_viz.run() remove_objs(point_viz, [ range_img, range_label, signal_img, signal_label, cloud_axis, cloud_xyz ]) # =============================================================== print("Ex 2.3:\tPoint Clouds: the LidarScanViz class") # [doc-stag-lidar-scan-viz] # Creating LidarScan visualizer (3D point cloud + field images on top) ls_viz = viz.LidarScanViz(meta, point_viz) # adding scan to the lidar scan viz ls_viz.scan = scan # refresh viz data ls_viz.draw() # visualize # update() is not needed for LidatScanViz because it's doing it internally point_viz.run() # [doc-etag-lidar-scan-viz] # =================================================== print("Ex 3.0:\tAugmenting point clouds with 3D Labels") # [doc-stag-lidar-scan-viz-labels] # Adding 3D Labels label1 = viz.Label("Label1: [1, 2, 4]", 1, 2, 4) point_viz.add(label1) label2 = viz.Label("Label2: [2, 1, 4]", 2, 1, 4) label2.set_scale(2) point_viz.add(label2) label3 = viz.Label("Label3: [4, 2, 1]", 4, 2, 1) label3.set_scale(3) point_viz.add(label3) # [doc-etag-lidar-scan-viz-labels] point_viz.camera.dolly(-100) # visualize point_viz.update() point_viz.run() # =============================================== print("Ex 4.0:\tOverlay 2D Images and 2D Labels") # [doc-stag-overlay-images-labels] # Adding image 1 with aspect ratio preserved img = viz.Image() img_data = make_checker_board(10, (2, 4)) mask_data = np.zeros((30, 30, 4)) mask_data[:15, :15] = np.array([1, 0, 0, 1]) img.set_mask(mask_data) img.set_image(img_data) ypos = (0, 0.5) xlen = (ypos[1] - ypos[0]) * img_data.shape[1] / img_data.shape[0] xpos = (0, xlen) img.set_position(*xpos, *ypos) img.set_hshift(-0.5) point_viz.add(img) # Adding Label for image 1: positioned at bottom left corner img_label = viz.Label("ARRrrr!", 0.25, 0.5) img_label.set_rgba((1.0, 1.0, 0.0, 1)) img_label.set_scale(2) point_viz.add(img_label) # Adding image 2: positioned to the right of the window img2 = viz.Image() img_data2 = make_checker_board(10, (4, 2)) mask_data2 = np.zeros((30, 30, 4)) mask_data2[15:25, 15:25] = np.array([0, 1, 0, 0.5]) img2.set_mask(mask_data2) img2.set_image(img_data2) ypos2 = (0, 0.5) xlen2 = (ypos2[1] - ypos2[0]) * img_data2.shape[1] / img_data2.shape[0] xpos2 = (-xlen2, 0) img2.set_position(*xpos2, *ypos2) img2.set_hshift(1.0) point_viz.add(img2) # Adding Label for image 2: positioned at top left corner img_label2 = viz.Label("Second", 1.0, 0.25, align_top=True, align_right=True) img_label2.set_rgba((0.0, 1.0, 1.0, 1)) img_label2.set_scale(1) point_viz.add(img_label2) # [doc-etag-overlay-images-labels] # visualize point_viz.update() point_viz.run() # =============================================================== print("Ex 5.0:\tAdding key handlers: 'R' for random camera dolly") # [doc-stag-key-handlers] def handle_dolly_random(ctx, key, mods) -> bool: if key == 82: # key R dolly_num = random.randrange(-15, 15) print(f"Random Dolly: {dolly_num}") point_viz.camera.dolly(dolly_num) point_viz.update() return True point_viz.push_key_handler(handle_dolly_random) # [doc-etag-key-handlers] # visualize point_viz.update() point_viz.run()