JH!jVerer0A+WxI{-^^#?39BX=B
z`ajT5-dUff?7p8kJ3nfiVEU<9Tr5M1?qKy%ogm8Qch_Ps321amTVXl%-D?pHEQ#q*
zYm&Rm<&ysn3oR6F7!
zrY0SswXN;LtvT9qcbzdN-6F4IGWGDP#|PGPLm>l_=!FA!Nm}$-dGj+@_9RvUTn#Jh
znWuQ^N;NcI{;UaXjTsD7oHcF?Xft;dij~@T9^~9sHa5k#BeP_S3zk7<>UVpSqvQwL
zIm!8!m9_+Hqq|36#>|OE|K6f~)IZweDQo5-6U5c!GvA-vvOaRUB-v@I%^UiKc!9oX
zGEIDuiO5}IgpsUZvn6?eJAgYj-RGdpNnc%=YT~Z`6u$mXNz-4!Bhu9EtJ3i1rB_=g
z1V3st^rU)v)WL^|1HY&Q3>*T)PUZjW(160BjlQTbIImSodxdGwVID85xm2oalewGp
z*2@`EfybWmK?W?r7M=D1kBBy#yrz>N5^D{xq}C35Im!k(LKyCKdL_@Uzb2_4U&$_E
ze~u~(sP_qlL1jj)Mi`IO{yY-or#w)>sGUFc^O$JF^GiC1DfEx;FRV|dsa=~Y;&W()
z?%N{FTY*O1#=EY%jTMK69X;6l&=388?+NYu1hMj>GqtVe;R(__{Su^eA99xfv(MK%
zeHPlf2W{5P#m;ifzJ(Q)Jr9Dr^G!dY@9Fh`@o1Kec*uX23TrY)`U_{QSoB`mv;Arz
zVXb*g{Q)MeHPLyB>j7}Rep`c3L~BL^cz<0?%GT%0V3gmxdIXVaf|nm$&|DMX1yss?
zLT1pH#-|zn*gn7;tq@3yK4yBDN~xMv*&?0lUx2X%>xDGssu_?a`SN$8hFm6C5qb%<
zzs>t)(_NnrJ=E@`?TR4a!HO!^zOW7u@8$@Swn+769vnQ(_+h>B
zTFy#J`p3ES`{U7LJ9I&(8VGq?Ro0Z~W8=;LB<-QIlU92BkdHM|y$5%}X~Fh_tbz~q
zlbX#N3jk-07y6J|(XQFY$3u(V&Q%JGa@}BfuG%R&b_w*d1Thz;J~Qg1V>?Szba&4o
ze3}osbQqj`#KhPg#DnBwE@u^u>S6*p07H^-z{gFDU0!yl7JT{5<4bL8@DeM>q1S7CaiaV@_6QoYC8OFcd~e${+Bbczy4Dx
zRlK;&^B6*B32c=UOLzWtMg#q}RBzna?cKcZE}|W^$980UuGqIr1N{)8ww6vfqs()R
zl{8NoN7U`?A^`zzQ7LtZL{Wr{V&leOP3RUZ)xX))Z2WiQW=(zNBGUg*5_}+GA+{?~
zqUICS{H;JirVS#L>aSA>V>1c=^zyH?VJ+_~cH@1$RRWqUhD
zCPA>qc3Mr2flr!`H2gr*wx7pi3;|B_cjqtAxoS1>(f586tfGs)Q;v&Ha4TzRRHoFq
ziye}wb(!w2(N{9lKv%)
z-nxm5t^Dz8meajijk2C^dSg8$MBeMN?2Um+X;JTvnmZaVwGg{3Wq;?i6QmPKQ6C%XxCku<
z{v}5}#FK(e1%p9JMGHja$omGnaWVD%A1p0PrThn>pXr1uqCo12^C%No1m3POn2eWDL*bjgW8$G|Xr(EE(a_(rma1p@9;#F|&3NTS0|_z{p`kt^AA
zIy<;KQ#*W8)LXFtfv(b(EYAj*$>D?CL?la9fY+mseSmG`6SU=gG9Q?U+_rhgw+rLxOzZSlm85wp
zm&Me0Q34*f-a66rsOPpP>*`828a@8d^l3ZjE8duL0hs+28Oi#{HYKNJpa8~mObG1;
z(s=+ZRAmi(_tSjX>--BHGfh-ZsWHgsakv7d;2+wAl8xYf6|^;pTN$miImO5Vlfn1R
znBy&lz08e|$vM^sYW~;GBS-6g9i0ax4RM9pKrovIc&_bTs-#y9PA*1?_@LBfiZXoA
z!~CtpLcS@05ss}kwz)bC)J%haxOk{+QE0`CfGFQj6lnIbXDnch>?bV6m-$TlEMAwr
z_@H70b>Q0|ByX-CRP3(4pI;c?n2vZBZ;=q=alI+2Qm1}A7gG+Bp}
zX6@uQrT=D2ll;NpXS`geO)tLSSe1;6BEByA$1$J}uv#X>vA1O&QgCaO{-G83H>$zB}74W?c(gZ9c=#6ly?CPP~Ce->?cFYX~@&O2-
zCjr)h_0yj7X@`0nHJ<;eR(o@GLC%WVCZ87vIk4Vf8Y>e{i;Swo6F{WzDsE{4%BH!w
zeMnA85@Z-ELnaLZdH$x8TLM{1K{{_e*-RY<{rtwAWS?~x&|ZH5nNO*S85;^VWfe-qk4NRrW4LSwY
z98*LSCknuD5E0$b$`EDe_*PT&+!8PIXB=b?NEJCLs(4|f9%-3XldgOWlC
zZAJ!$w?TT@p!j6GO6iXJcSnBMYXJCr3L*maKLS{ThTO52hK)bdR77v@=gU6_rC*&h
zSxwz0Jz8nbl=lFOGwr3v3~obQh(Mz0Y;aKeV?+^vupSq>t0$O4p-wblc7}Juqo{AyBaZF!}{*41rCXw-n-ZEe3LgcB_d^
z1wDhPK#lEV5P%}PDuwzMIM3Y&68&($^kM78)q?HZM}{_R21VQ>phC4OsGGfUCm-ZM
z3B+y9XS>Ojd(Q{5_ZtR7_-8!Y&aCG_2h6y$e&<1KJ9s5vZ}!L5Jj34>1PJ8viGKQQ
zQYh(lh2cnnN(ZnE6k>odpVR)&K@GNTQ2M#i(^kPN&DwSO!0W;Ffa~-!SnPQnj$hk1
z?a~+ETBmK$0cD281!&Kn1TPL2g-gTY9OdiF^;Sdd3emjDB?b0Z*0u7u;`C+v0!xI_
zYhP?e4fxa^d>THTb+~Z|KKsay!usWo2-qu|p7m8(^i}R=`HAnR+y+%cjWrqG(Cbl8
zaEAQp$tnr5=e!Rvx&9Kug*1hgavIHW%L}h4tNu|CzGhym;7%7DLk4o)TS^-e7y#O_
zAruIm-xtMF%cD1McwNf$j%Ojk`w5O&JVu;-zYlykCwZyux(@C_6TNQmC+CwtG{9~8
zN%u=_Z`e|0{6o>^7EM_KGCm6Tel5XahA*-;sAaYjp6XV#0W-9|u`)ALMHYT?w{fFG<54sN1_d62&R1
z*D{z`%AjFxy&GlvJqLH&EQA$qio&2ra)NDF?pzl2K(K2Dl*5ouCOYp0cbK6CLzZ(z
zN@DME7#^J)d)tn7Q?^xIBw1WI91k4VX&)aB8}K7)gKO6^?GMiYCYIarAHnOfG1PYz
zUk3E6-n|m>!GpU!YAhoBrC|X;_34!Bcc82rG=vvgPf>qba>^3%l>K@!;2-EWvEv32
z{Ws;uQ-eV{@VFE34IBr?eq=8bpFbV2c~`R0fAV!Or~=OGrBZkdU{hCaeS*!Wk>-au
zRkyR*b=;a;llpOG+W48TAMSGA&zXv;r`J9c+rCumV`)WrqozPL)SX^BkTfVvdX-0$
zE7ooM`Z9R&&w|BSWQb7_)#LV(fQ5^oNZfq&;w~S`zj^E*Y^>n2_at$y%29F15ML41
zxJ%7c>UcbfjF$o)C>jTZH^ATjmny#9DuZlpD%Q*zSvq&cEScZf0SXqVFHI95f(w)b
zeCnN>>eBwx=BvNG8LU9@!_Zs?(SW;+=&X^18qn9V{B61AQt_J`nf!o?22i2i#5+lb
z>F+NhRDhEHH_~2mQ64$uEbD*oj%b!YAoC(UEiI7^)g@H`UZQ+~m0xSVH
z{Zyv%LGiej0rg}|<=o%h&GZ4k4Wu9tT5s@-uJ0J(Or|qiGwh}cxU3-16!G$>n{pW_
zG!5p+G{k?d8Yr07haS7-ij(}b
zWoh5NX9b*ar|Dz`hGL4YTXFl&O(PzwQTc?@cDGmzN;>3k0~QY`R;KC9;55rCGk|*4
zR50J^+q%PX(}LbVH-c9AHcP1t97RVb2%K&`U?yc*SK;dh3|DOIO)X&W{iw8;zdY>OwY919)7jKk#{WJ2OsEn;M5RpXgw1Ef|_3eHGOeN
zl}C5~?~e}XYXY^#|NBh>U=03$@g0U)pdJQy>)oc%
VZHA12E1=h)7s^`CN|h`_|1THltRw&c
diff --git a/apps/dash-lyft-explorer/assets/demo.gif b/apps/dash-lyft-explorer/assets/github/demo.gif
similarity index 100%
rename from apps/dash-lyft-explorer/assets/demo.gif
rename to apps/dash-lyft-explorer/assets/github/demo.gif
diff --git a/apps/dash-lyft-explorer/assets/images/dash-logo.png b/apps/dash-lyft-explorer/assets/images/dash-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..984dd57ab53b7f9fa47df219e25df91a0885613d
GIT binary patch
literal 23021
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: {name}"}),
+ body=True,
+ style={"height": "calc(95vh - 215px)"},
+)
\ No newline at end of file
diff --git a/apps/dash-lyft-explorer/utils/helper_functions.py b/apps/dash-lyft-explorer/utils/helper_functions.py
new file mode 100644
index 000000000..8a179e137
--- /dev/null
+++ b/apps/dash-lyft-explorer/utils/helper_functions.py
@@ -0,0 +1,15 @@
+def unsnake(st):
+ """
+ Converts a string with _ to space.
+ """
+ return st.replace("_", " ").title()
+
+def get_token_list(scene, lv5):
+ token_list = [scene["first_sample_token"]]
+ sample = lv5.get("sample", token_list[0])
+
+ while sample["next"] != "":
+ token_list.append(sample["next"])
+ sample = lv5.get("sample", sample["next"])
+
+ return token_list
\ No newline at end of file
diff --git a/apps/dash-lyft-explorer/utils/model.py b/apps/dash-lyft-explorer/utils/model.py
new file mode 100644
index 000000000..f9d94300a
--- /dev/null
+++ b/apps/dash-lyft-explorer/utils/model.py
@@ -0,0 +1,159 @@
+import plotly.graph_objects as go
+import plotly.express as px
+import numpy as np
+import pydeck as pdk
+from PIL import Image
+
+from constants import NAME2COLOR
+
+def build_deck(mode, pc_df, polygon_data):
+ if mode == "first_person":
+ view = pdk.View(type="FirstPersonView", controller=True)
+ view_state = pdk.ViewState(latitude=0, longitude=0, bearing=-90, pitch=15)
+ point_size = 10
+ elif mode == "orbit":
+ view = pdk.View(type="OrbitView", controller=True)
+ view_state = pdk.ViewState(
+ target=[0, 0, 1e-5],
+ controller=True,
+ zoom=23,
+ rotation_orbit=-90,
+ rotation_x=15,
+ )
+ point_size = 3
+
+ else:
+ view_state = pdk.ViewState(
+ latitude=0,
+ longitude=0,
+ bearing=45,
+ pitch=50,
+ zoom=20,
+ max_zoom=30,
+ position=[0, 0, 1e-5],
+ )
+ view = pdk.View(type="MapView", controller=True)
+ point_size = 1
+
+ pc_layer = pdk.Layer(
+ "PointCloudLayer",
+ data=pc_df,
+ get_position=["x", "y", "z"],
+ get_color=[255, 255, 255],
+ auto_highlight=True,
+ pickable=False,
+ point_size=point_size,
+ coordinate_system=2,
+ coordinate_origin=[0, 0],
+ )
+
+ box_layer = pdk.Layer(
+ "PolygonLayer",
+ data=polygon_data,
+ stroked=True,
+ pickable=True,
+ filled=True,
+ extruded=True,
+ opacity=0.2,
+ wireframe=True,
+ line_width_min_pixels=1,
+ get_polygon="polygon",
+ get_fill_color="color",
+ get_line_color=[255, 255, 255],
+ get_line_width=0,
+ coordinate_system=2,
+ get_elevation="elevation",
+ )
+
+ tooltip = {"html": "Label: {name}"}
+
+ r = pdk.Deck(
+ [pc_layer, box_layer],
+ initial_view_state=view_state,
+ views=[view],
+ tooltip=tooltip,
+ map_provider=None,
+ )
+
+ return r
+
+
+def compute_pointcloud_for_image(
+ lv5,
+ sample_token: str,
+ dot_size: int = 2,
+ pointsensor_channel: str = "LIDAR_TOP",
+ camera_channel: str = "CAM_FRONT",
+ out_path: str = None,
+):
+ """Scatter-plots a point-cloud on top of image.
+ Args:
+ sample_token: Sample token.
+ dot_size: Scatter plot dot size.
+ pointsensor_channel: RADAR or LIDAR channel name, e.g. 'LIDAR_TOP'.
+ camera_channel: Camera channel name, e.g. 'CAM_FRONT'.
+ out_path: Optional path to save the rendered figure to disk.
+ Returns:
+ tuple containing the points, array of colors and a pillow image
+ """
+ sample_record = lv5.get("sample", sample_token)
+
+ # Here we just grab the front camera and the point sensor.
+ pointsensor_token = sample_record["data"][pointsensor_channel]
+ camera_token = sample_record["data"][camera_channel]
+
+ points, coloring, im = lv5.explorer.map_pointcloud_to_image(
+ pointsensor_token, camera_token
+ )
+
+ return points, coloring, im
+
+
+def render_box_in_image(lv5, im, sample: str, camera_channel: str):
+ camera_token = sample["data"][camera_channel]
+ data_path, boxes, camera_intrinsic = lv5.get_sample_data(
+ camera_token, flat_vehicle_coordinates=False
+ )
+
+ arr = np.array(im)
+
+ for box in boxes:
+ c = NAME2COLOR[box.name]
+ box.render_cv2(arr, normalize=True, view=camera_intrinsic, colors=(c, c, c))
+
+ new = Image.fromarray(arr)
+ return new
+
+
+def build_figure(lv5, sample, lidar, camera, overlay):
+ points, coloring, im = compute_pointcloud_for_image(
+ lv5, sample["token"], pointsensor_channel=lidar, camera_channel=camera
+ )
+
+ if "boxes" in overlay:
+ im = render_box_in_image(lv5, im, sample, camera_channel=camera)
+
+ fig = px.imshow(im, binary_format="jpeg", binary_compression_level=2)
+
+ if "pointcloud" in overlay:
+ fig.add_trace(
+ go.Scattergl(
+ x=points[0,],
+ y=points[1,],
+ mode="markers",
+ opacity=0.4,
+ marker_color=coloring,
+ marker_size=3,
+ )
+ )
+
+ fig.update_layout(
+ margin=dict(l=10, r=10, t=0, b=0),
+ paper_bgcolor="rgba(0,0,0,0)",
+ plot_bgcolor="rgba(0,0,0,0)",
+ hovermode=False,
+ )
+ fig.update_xaxes(showticklabels=False, showgrid=False, range=(0, im.size[0]))
+ fig.update_yaxes(showticklabels=False, showgrid=False, range=(im.size[1], 0))
+
+ return fig
From 5fb128e9264e2a23c22caad2f4223515d6a3b6a1 Mon Sep 17 00:00:00 2001
From: admin <51248046+danton267@users.noreply.github.com>
Date: Thu, 19 May 2022 23:18:49 +0100
Subject: [PATCH 2/2] v2
---
apps/dash-lyft-explorer/requirements.txt | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/apps/dash-lyft-explorer/requirements.txt b/apps/dash-lyft-explorer/requirements.txt
index a78bbebd8..0e5ee0855 100644
--- a/apps/dash-lyft-explorer/requirements.txt
+++ b/apps/dash-lyft-explorer/requirements.txt
@@ -6,8 +6,4 @@ numpy==1.22.3
colorlover==0.3.0
lyft-dataset-sdk==0.0.8
pydeck==0.7.1
-gunicorn==20.1.0
-
-pydeck==0.5.*
-Pillow
-opencv-python==4.2.0.34
+gunicorn==20.1.0
\ No newline at end of file