"""Copyright (c) 2021, Ouster, Inc.All rights reserved.Example of custom visualizer use.Intended to run with `python -m ouster.sdk.examples.viz`"""importargparsefromousterimportclient,pcapfromouster.sdkimportvizimportosimportsysimportnumpyasnpimportrandom
[docs]defmake_checker_board(square_size,reps):"""Makes a test checker board image."""img_data=np.full((square_size,square_size),0)img_data=np.hstack([img_data,np.logical_xor(img_data,1)])img_data=np.vstack([img_data,np.logical_xor(img_data,1)])img_data=np.tile(img_data,reps)returnimg_data
# Helper method to remove list of objects from point_vizdefremove_objs(point_viz,objs):forobjinobjs:point_viz.remove(obj)# currently we need to always call update()/run_once() after some object removespoint_viz.update()point_viz.run_once()
[docs]defmain():"""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)ifnotpcap_pathornotmeta_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 sourcesmeta=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 instancepoint_viz=viz.PointViz("Example Viz")viz.add_default_controls(point_viz)# ... add objects here# update internal objects buffers and run visualizerpoint_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]# visualizepoint_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 leftimg.set_position(0,1,-0.5,0.5)img.set_hshift(-1)# [doc-etag-image-pos-left]# visualizepoint_viz.update()point_viz.run()# [doc-stag-image-pos-right]# move img to the rightimg.set_position(-1,0,-0.5,0.5)img.set_hshift(1)# [doc-etag-image-pos-right]# visualizepoint_viz.update()point_viz.run()# [doc-stag-image-pos-right-bottom]# move img to the right bottomimg.set_position(-1,0,-1,0)img.set_hshift(1)# [doc-etag-image-pos-right-bottom]# visualizepoint_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.0img_screen_height=0.4# [0..2]img_screen_len=img_screen_height/img_aspect# prepare field dataranges=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.REFLECTIVITY)signal=client.destagger(meta,signal)signal=np.divide(signal,np.amax(signal),dtype=np.float32)# creating Image viz elementsrange_img=viz.Image()range_img.set_image(ranges)# top center positionrange_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.0img_screen_height=0.4# [0..2]img_screen_len=img_screen_height/img_aspect# bottom center positionsignal_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]# visualizepoint_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.REFLECTIVITY),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]# visualizepoint_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]# visualizepoint_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 pointsxyzlut=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)# visualizepoint_viz.update()point_viz.run()# =======================================================print("Ex 2.2:\tPoint Clouds: Custom Axes Helper as Unstructured Points")# [doc-stag-axes-helper]# basis vectorsx_=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=100line=np.linspace(0,1,axis_n).reshape((1,-1))# basis vector to point cloudaxis_points=np.hstack((x_@line,y_@line,z_@line)).transpose()# colors for basis vectorsaxis_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)# visualizepoint_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 vizls_viz.scan=scan# refresh viz datals_viz.draw()# visualize# update() is not needed for LidatScanViz because it's doing it internallypoint_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 Labelslabel1=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)# visualizepoint_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 preservedimg=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 cornerimg_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 windowimg2=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 cornerimg_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]# visualizepoint_viz.update()point_viz.run()# ===============================================================print("Ex 5.0:\tAdding key handlers: 'R' for random camera dolly")# [doc-stag-key-handlers]defhandle_dolly_random(ctx,key,mods)->bool:ifkey==82:# key Rdolly_num=random.randrange(-15,15)print(f"Random Dolly: {dolly_num}")point_viz.camera.dolly(dolly_num)point_viz.update()returnTruepoint_viz.push_key_handler(handle_dolly_random)# [doc-etag-key-handlers]# visualizepoint_viz.update()point_viz.run()
# That's all folks! Happy hacking!if__name__=="__main__":main()