Initial commit
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"camera_matrix": [
|
||||
[
|
||||
1920.0,
|
||||
0.0,
|
||||
960.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
1920.0,
|
||||
540.0
|
||||
],
|
||||
[
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
],
|
||||
"rotation_vector": [
|
||||
-0.7801686952693866,
|
||||
0.8941439646078098,
|
||||
0.6741747541455946
|
||||
],
|
||||
"translation_vector": [
|
||||
-1.1214146556912021,
|
||||
-3.8975183875481156,
|
||||
24.026959814106053
|
||||
],
|
||||
"rotation_matrix": [
|
||||
[
|
||||
0.46447638978533573,
|
||||
-0.7814338577335282,
|
||||
0.41668070428048015
|
||||
],
|
||||
[
|
||||
0.18562725756007864,
|
||||
0.5459705583002341,
|
||||
0.8169814384183126
|
||||
],
|
||||
[
|
||||
-0.8659123538688573,
|
||||
-0.30212129262438064,
|
||||
0.3986458578240444
|
||||
]
|
||||
],
|
||||
"reprojection_error": 124.420654296875,
|
||||
"focal_length": 1920.0,
|
||||
"principal_point": [
|
||||
960.0,
|
||||
540.0
|
||||
],
|
||||
"image_size": [
|
||||
1920,
|
||||
1080
|
||||
],
|
||||
"calibrated": true
|
||||
}
|
||||
@@ -0,0 +1,802 @@
|
||||
[
|
||||
{
|
||||
"frame": 0,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 1,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 2,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 3,
|
||||
"x_m": 10.044878959655762,
|
||||
"y_m": 3.3315815925598145,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4595355987548828
|
||||
},
|
||||
{
|
||||
"frame": 4,
|
||||
"x_m": 9.925751686096191,
|
||||
"y_m": 3.282414674758911,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7499630451202393
|
||||
},
|
||||
{
|
||||
"frame": 5,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 6,
|
||||
"x_m": 9.522378921508789,
|
||||
"y_m": 3.081491708755493,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4438209533691406
|
||||
},
|
||||
{
|
||||
"frame": 7,
|
||||
"x_m": 9.406031608581543,
|
||||
"y_m": 3.0407073497772217,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.8662319779396057
|
||||
},
|
||||
{
|
||||
"frame": 8,
|
||||
"x_m": 9.371339797973633,
|
||||
"y_m": 3.0464587211608887,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9164504408836365
|
||||
},
|
||||
{
|
||||
"frame": 9,
|
||||
"x_m": 9.37229061126709,
|
||||
"y_m": 3.072193145751953,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9407913088798523
|
||||
},
|
||||
{
|
||||
"frame": 10,
|
||||
"x_m": 9.378125190734863,
|
||||
"y_m": 3.1054039001464844,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9483180642127991
|
||||
},
|
||||
{
|
||||
"frame": 11,
|
||||
"x_m": 9.478368759155273,
|
||||
"y_m": 3.180798053741455,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9082649350166321
|
||||
},
|
||||
{
|
||||
"frame": 12,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 13,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 14,
|
||||
"x_m": 9.910148620605469,
|
||||
"y_m": 3.5509445667266846,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.667772114276886
|
||||
},
|
||||
{
|
||||
"frame": 15,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 16,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 17,
|
||||
"x_m": 8.93185043334961,
|
||||
"y_m": 2.7611701488494873,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.5858595967292786
|
||||
},
|
||||
{
|
||||
"frame": 18,
|
||||
"x_m": 8.352518081665039,
|
||||
"y_m": 2.2731122970581055,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.8277773857116699
|
||||
},
|
||||
{
|
||||
"frame": 19,
|
||||
"x_m": 7.649472713470459,
|
||||
"y_m": 1.729779601097107,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6525294780731201
|
||||
},
|
||||
{
|
||||
"frame": 20,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 21,
|
||||
"x_m": 6.449870586395264,
|
||||
"y_m": 0.7403887510299683,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9178251624107361
|
||||
},
|
||||
{
|
||||
"frame": 22,
|
||||
"x_m": 5.954407215118408,
|
||||
"y_m": 0.2702276408672333,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6851440668106079
|
||||
},
|
||||
{
|
||||
"frame": 23,
|
||||
"x_m": 5.351879596710205,
|
||||
"y_m": -0.2799437344074249,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.8174329400062561
|
||||
},
|
||||
{
|
||||
"frame": 24,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 25,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 26,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 27,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 28,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 29,
|
||||
"x_m": 4.331277370452881,
|
||||
"y_m": -1.5349446535110474,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7200624942779541
|
||||
},
|
||||
{
|
||||
"frame": 30,
|
||||
"x_m": 4.433146953582764,
|
||||
"y_m": -1.5207486152648926,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4647325277328491
|
||||
},
|
||||
{
|
||||
"frame": 31,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 32,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 33,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 34,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 35,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 36,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 37,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 38,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 39,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 40,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 41,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 42,
|
||||
"x_m": 8.577290534973145,
|
||||
"y_m": 1.0078997611999512,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4238705635070801
|
||||
},
|
||||
{
|
||||
"frame": 43,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 44,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 45,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 46,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 47,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 48,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 49,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 50,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 51,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 52,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 53,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 54,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 55,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 56,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 57,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 58,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 59,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 60,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 61,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 62,
|
||||
"x_m": -1.4370819330215454,
|
||||
"y_m": -4.089122772216797,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.46716606616973877
|
||||
},
|
||||
{
|
||||
"frame": 63,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 64,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 65,
|
||||
"x_m": -3.1526687145233154,
|
||||
"y_m": -3.9628825187683105,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7788172364234924
|
||||
},
|
||||
{
|
||||
"frame": 66,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 67,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 68,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 69,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 70,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 71,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 72,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 73,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 74,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 75,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 76,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 77,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 78,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 79,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 80,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 81,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 82,
|
||||
"x_m": 5.462012767791748,
|
||||
"y_m": 4.150640964508057,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7371496558189392
|
||||
},
|
||||
{
|
||||
"frame": 83,
|
||||
"x_m": 6.035140037536621,
|
||||
"y_m": 4.453850746154785,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.47047895193099976
|
||||
},
|
||||
{
|
||||
"frame": 84,
|
||||
"x_m": 6.361359596252441,
|
||||
"y_m": 4.682921409606934,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7571220993995667
|
||||
},
|
||||
{
|
||||
"frame": 85,
|
||||
"x_m": 5.944571495056152,
|
||||
"y_m": 4.653173923492432,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6384866237640381
|
||||
},
|
||||
{
|
||||
"frame": 86,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 87,
|
||||
"x_m": 5.069350242614746,
|
||||
"y_m": 4.607361316680908,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.924823522567749
|
||||
},
|
||||
{
|
||||
"frame": 88,
|
||||
"x_m": 4.626520156860352,
|
||||
"y_m": 4.583075046539307,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6589019298553467
|
||||
},
|
||||
{
|
||||
"frame": 89,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 90,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 91,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 92,
|
||||
"x_m": 3.593766450881958,
|
||||
"y_m": 4.720729351043701,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.616001307964325
|
||||
},
|
||||
{
|
||||
"frame": 93,
|
||||
"x_m": 3.4283807277679443,
|
||||
"y_m": 4.76817512512207,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7801673412322998
|
||||
},
|
||||
{
|
||||
"frame": 94,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 95,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
},
|
||||
{
|
||||
"frame": 96,
|
||||
"x_m": 3.5402987003326416,
|
||||
"y_m": 5.051088809967041,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9100144505500793
|
||||
},
|
||||
{
|
||||
"frame": 97,
|
||||
"x_m": 3.6705820560455322,
|
||||
"y_m": 5.15645694732666,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9327566623687744
|
||||
},
|
||||
{
|
||||
"frame": 98,
|
||||
"x_m": 3.850410223007202,
|
||||
"y_m": 5.273887634277344,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7828439474105835
|
||||
},
|
||||
{
|
||||
"frame": 99,
|
||||
"x_m": null,
|
||||
"y_m": null,
|
||||
"z_m": null,
|
||||
"on_ground": false,
|
||||
"confidence": 0.0
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"viewer_path": "data/6350640e-9cf2-4894-ad25-88cd83ed818e/viewer/index.html",
|
||||
"num_frames": 31
|
||||
}
|
||||
16
data/6350640e-9cf2-4894-ad25-88cd83ed818e/detect_net.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"net_corners_pixel": [
|
||||
[
|
||||
697.8789672851562,
|
||||
383.0556640625
|
||||
],
|
||||
[
|
||||
1397.933349609375,
|
||||
632.2061309814453
|
||||
]
|
||||
],
|
||||
"net_height_m": 0.914,
|
||||
"detection_confidence": 1.0,
|
||||
"frame_width": 1920,
|
||||
"frame_height": 1080
|
||||
}
|
||||
|
After Width: | Height: | Size: 488 KiB |
|
After Width: | Height: | Size: 488 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 491 KiB |
|
After Width: | Height: | Size: 492 KiB |
|
After Width: | Height: | Size: 492 KiB |
|
After Width: | Height: | Size: 492 KiB |
|
After Width: | Height: | Size: 492 KiB |
|
After Width: | Height: | Size: 491 KiB |
|
After Width: | Height: | Size: 491 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 491 KiB |
|
After Width: | Height: | Size: 475 KiB |
|
After Width: | Height: | Size: 487 KiB |
|
After Width: | Height: | Size: 479 KiB |
|
After Width: | Height: | Size: 483 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 491 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 490 KiB |
|
After Width: | Height: | Size: 491 KiB |
|
After Width: | Height: | Size: 480 KiB |
|
After Width: | Height: | Size: 481 KiB |
|
After Width: | Height: | Size: 485 KiB |
|
After Width: | Height: | Size: 486 KiB |
|
After Width: | Height: | Size: 488 KiB |
831
data/6350640e-9cf2-4894-ad25-88cd83ed818e/viewer/index.html
Normal file
@@ -0,0 +1,831 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ball Tracking 3D Viewer - Run 6350640e</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
background: #1a1a1a;
|
||||
color: #ffffff;
|
||||
padding: 20px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 25px;
|
||||
font-size: 28px;
|
||||
color: #00ff88;
|
||||
}
|
||||
|
||||
.viewer {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: #2a2a2a;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel h2 {
|
||||
margin-bottom: 15px;
|
||||
font-size: 18px;
|
||||
color: #00ff88;
|
||||
}
|
||||
|
||||
#frameImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#canvas3d {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.controls {
|
||||
background: #2a2a2a;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.controls-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #00ff88;
|
||||
color: #1a1a1a;
|
||||
border: none;
|
||||
padding: 10px 24px;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #00cc6a;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
background: #444;
|
||||
color: #888;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
flex: 1;
|
||||
height: 6px;
|
||||
background: #444;
|
||||
border-radius: 3px;
|
||||
outline: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background: #00ff88;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="range"]::-moz-range-thumb {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background: #00ff88;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
background: #1a1a1a;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #00ff88;
|
||||
}
|
||||
|
||||
.kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 8px;
|
||||
background: #444;
|
||||
border-radius: 3px;
|
||||
font-family: monospace;
|
||||
font-size: 14px;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.help {
|
||||
margin-top: 15px;
|
||||
padding: 10px;
|
||||
background: #1a1a1a;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🎾 Pickleball Ball Tracking 3D Viewer</h1>
|
||||
|
||||
<div class="viewer">
|
||||
<div class="panel">
|
||||
<h2>📹 Video Frame</h2>
|
||||
<img id="frameImage" alt="Video frame">
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<h2>🗺️ Interactive 3D Court (drag to rotate, scroll to zoom)</h2>
|
||||
<div id="canvas3d"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<div class="controls-row">
|
||||
<button id="prevBtn">← Prev</button>
|
||||
<input type="range" id="frameSlider" min="0" max="0" value="0">
|
||||
<button id="nextBtn">Next →</button>
|
||||
<button id="playBtn">▶ Play</button>
|
||||
</div>
|
||||
|
||||
<div class="info">
|
||||
<div class="info-item">
|
||||
<div class="info-label">Frame</div>
|
||||
<div class="info-value" id="frameNum">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">X Position (m)</div>
|
||||
<div class="info-value" id="posX">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">Y Position (m)</div>
|
||||
<div class="info-value" id="posY">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">Z Height (m)</div>
|
||||
<div class="info-value" id="posZ">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">Confidence</div>
|
||||
<div class="info-value" id="confidence">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">On Ground</div>
|
||||
<div class="info-value" id="onGround">-</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="help">
|
||||
💡 <strong>Controls:</strong>
|
||||
<span class="kbd">←/→</span> Navigate frames
|
||||
<span class="kbd">Space</span> Play/Pause
|
||||
<span class="kbd">Mouse drag</span> Rotate 3D view
|
||||
<span class="kbd">Mouse wheel</span> Zoom
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Three.js from CDN -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
||||
<script>
|
||||
// Frame data from Python
|
||||
const framesData = [
|
||||
{
|
||||
"frame": 3,
|
||||
"x_m": 10.044878959655762,
|
||||
"y_m": 3.3315815925598145,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4595355987548828
|
||||
},
|
||||
{
|
||||
"frame": 4,
|
||||
"x_m": 9.925751686096191,
|
||||
"y_m": 3.282414674758911,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7499630451202393
|
||||
},
|
||||
{
|
||||
"frame": 6,
|
||||
"x_m": 9.522378921508789,
|
||||
"y_m": 3.081491708755493,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4438209533691406
|
||||
},
|
||||
{
|
||||
"frame": 7,
|
||||
"x_m": 9.406031608581543,
|
||||
"y_m": 3.0407073497772217,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.8662319779396057
|
||||
},
|
||||
{
|
||||
"frame": 8,
|
||||
"x_m": 9.371339797973633,
|
||||
"y_m": 3.0464587211608887,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9164504408836365
|
||||
},
|
||||
{
|
||||
"frame": 9,
|
||||
"x_m": 9.37229061126709,
|
||||
"y_m": 3.072193145751953,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9407913088798523
|
||||
},
|
||||
{
|
||||
"frame": 10,
|
||||
"x_m": 9.378125190734863,
|
||||
"y_m": 3.1054039001464844,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9483180642127991
|
||||
},
|
||||
{
|
||||
"frame": 11,
|
||||
"x_m": 9.478368759155273,
|
||||
"y_m": 3.180798053741455,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9082649350166321
|
||||
},
|
||||
{
|
||||
"frame": 14,
|
||||
"x_m": 9.910148620605469,
|
||||
"y_m": 3.5509445667266846,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.667772114276886
|
||||
},
|
||||
{
|
||||
"frame": 17,
|
||||
"x_m": 8.93185043334961,
|
||||
"y_m": 2.7611701488494873,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.5858595967292786
|
||||
},
|
||||
{
|
||||
"frame": 18,
|
||||
"x_m": 8.352518081665039,
|
||||
"y_m": 2.2731122970581055,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.8277773857116699
|
||||
},
|
||||
{
|
||||
"frame": 19,
|
||||
"x_m": 7.649472713470459,
|
||||
"y_m": 1.729779601097107,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6525294780731201
|
||||
},
|
||||
{
|
||||
"frame": 21,
|
||||
"x_m": 6.449870586395264,
|
||||
"y_m": 0.7403887510299683,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9178251624107361
|
||||
},
|
||||
{
|
||||
"frame": 22,
|
||||
"x_m": 5.954407215118408,
|
||||
"y_m": 0.2702276408672333,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6851440668106079
|
||||
},
|
||||
{
|
||||
"frame": 23,
|
||||
"x_m": 5.351879596710205,
|
||||
"y_m": -0.2799437344074249,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.8174329400062561
|
||||
},
|
||||
{
|
||||
"frame": 29,
|
||||
"x_m": 4.331277370452881,
|
||||
"y_m": -1.5349446535110474,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7200624942779541
|
||||
},
|
||||
{
|
||||
"frame": 30,
|
||||
"x_m": 4.433146953582764,
|
||||
"y_m": -1.5207486152648926,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4647325277328491
|
||||
},
|
||||
{
|
||||
"frame": 42,
|
||||
"x_m": 8.577290534973145,
|
||||
"y_m": 1.0078997611999512,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.4238705635070801
|
||||
},
|
||||
{
|
||||
"frame": 62,
|
||||
"x_m": -1.4370819330215454,
|
||||
"y_m": -4.089122772216797,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.46716606616973877
|
||||
},
|
||||
{
|
||||
"frame": 65,
|
||||
"x_m": -3.1526687145233154,
|
||||
"y_m": -3.9628825187683105,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7788172364234924
|
||||
},
|
||||
{
|
||||
"frame": 82,
|
||||
"x_m": 5.462012767791748,
|
||||
"y_m": 4.150640964508057,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7371496558189392
|
||||
},
|
||||
{
|
||||
"frame": 83,
|
||||
"x_m": 6.035140037536621,
|
||||
"y_m": 4.453850746154785,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.47047895193099976
|
||||
},
|
||||
{
|
||||
"frame": 84,
|
||||
"x_m": 6.361359596252441,
|
||||
"y_m": 4.682921409606934,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7571220993995667
|
||||
},
|
||||
{
|
||||
"frame": 85,
|
||||
"x_m": 5.944571495056152,
|
||||
"y_m": 4.653173923492432,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6384866237640381
|
||||
},
|
||||
{
|
||||
"frame": 87,
|
||||
"x_m": 5.069350242614746,
|
||||
"y_m": 4.607361316680908,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.924823522567749
|
||||
},
|
||||
{
|
||||
"frame": 88,
|
||||
"x_m": 4.626520156860352,
|
||||
"y_m": 4.583075046539307,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.6589019298553467
|
||||
},
|
||||
{
|
||||
"frame": 92,
|
||||
"x_m": 3.593766450881958,
|
||||
"y_m": 4.720729351043701,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.616001307964325
|
||||
},
|
||||
{
|
||||
"frame": 93,
|
||||
"x_m": 3.4283807277679443,
|
||||
"y_m": 4.76817512512207,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7801673412322998
|
||||
},
|
||||
{
|
||||
"frame": 96,
|
||||
"x_m": 3.5402987003326416,
|
||||
"y_m": 5.051088809967041,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9100144505500793
|
||||
},
|
||||
{
|
||||
"frame": 97,
|
||||
"x_m": 3.6705820560455322,
|
||||
"y_m": 5.15645694732666,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.9327566623687744
|
||||
},
|
||||
{
|
||||
"frame": 98,
|
||||
"x_m": 3.850410223007202,
|
||||
"y_m": 5.273887634277344,
|
||||
"z_m": 0.0,
|
||||
"on_ground": true,
|
||||
"confidence": 0.7828439474105835
|
||||
}
|
||||
];
|
||||
|
||||
let currentIndex = 0;
|
||||
let isPlaying = false;
|
||||
let playInterval = null;
|
||||
|
||||
// DOM elements
|
||||
const frameImage = document.getElementById('frameImage');
|
||||
const canvas3dContainer = document.getElementById('canvas3d');
|
||||
const prevBtn = document.getElementById('prevBtn');
|
||||
const nextBtn = document.getElementById('nextBtn');
|
||||
const playBtn = document.getElementById('playBtn');
|
||||
const frameSlider = document.getElementById('frameSlider');
|
||||
const frameNum = document.getElementById('frameNum');
|
||||
const posX = document.getElementById('posX');
|
||||
const posY = document.getElementById('posY');
|
||||
const posZ = document.getElementById('posZ');
|
||||
const confidence = document.getElementById('confidence');
|
||||
const onGround = document.getElementById('onGround');
|
||||
|
||||
// Initialize
|
||||
frameSlider.max = framesData.length - 1;
|
||||
|
||||
// Setup Three.js scene
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0x1a1a1a);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
60,
|
||||
canvas3dContainer.clientWidth / canvas3dContainer.clientHeight,
|
||||
0.1,
|
||||
1000
|
||||
);
|
||||
camera.position.set(15, 12, 15);
|
||||
camera.lookAt(6.7, 3, 0);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setSize(canvas3dContainer.clientWidth, canvas3dContainer.clientHeight);
|
||||
canvas3dContainer.appendChild(renderer.domElement);
|
||||
|
||||
// Lighting
|
||||
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
||||
scene.add(ambientLight);
|
||||
|
||||
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||
directionalLight.position.set(10, 20, 10);
|
||||
scene.add(directionalLight);
|
||||
|
||||
// Grid helper
|
||||
const gridHelper = new THREE.GridHelper(20, 20, 0x444444, 0x222222);
|
||||
scene.add(gridHelper);
|
||||
|
||||
// Court dimensions
|
||||
const courtLength = 13.4;
|
||||
const courtWidth = 6.1;
|
||||
const netHeight = 0.914;
|
||||
|
||||
// Court floor (green)
|
||||
const courtGeometry = new THREE.PlaneGeometry(courtLength, courtWidth);
|
||||
const courtMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0x00aa44,
|
||||
side: THREE.DoubleSide,
|
||||
roughness: 0.8
|
||||
});
|
||||
const court = new THREE.Mesh(courtGeometry, courtMaterial);
|
||||
court.rotation.x = -Math.PI / 2;
|
||||
court.position.set(courtLength / 2, 0, courtWidth / 2);
|
||||
scene.add(court);
|
||||
|
||||
// Court boundaries (white lines)
|
||||
const boundaryMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 3 });
|
||||
const boundaryPoints = [
|
||||
new THREE.Vector3(0, 0.01, 0),
|
||||
new THREE.Vector3(courtLength, 0.01, 0),
|
||||
new THREE.Vector3(courtLength, 0.01, courtWidth),
|
||||
new THREE.Vector3(0, 0.01, courtWidth),
|
||||
new THREE.Vector3(0, 0.01, 0)
|
||||
];
|
||||
const boundaryGeometry = new THREE.BufferGeometry().setFromPoints(boundaryPoints);
|
||||
const boundary = new THREE.Line(boundaryGeometry, boundaryMaterial);
|
||||
scene.add(boundary);
|
||||
|
||||
// Net (mesh) - positioned at middle of court LENGTH (X=6.7m), spanning full WIDTH (Z axis)
|
||||
const netGeometry = new THREE.BoxGeometry(0.05, netHeight, courtWidth);
|
||||
const netMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0xcccccc,
|
||||
transparent: true,
|
||||
opacity: 0.7,
|
||||
side: THREE.DoubleSide
|
||||
});
|
||||
const net = new THREE.Mesh(netGeometry, netMaterial);
|
||||
net.position.set(courtLength / 2, netHeight / 2, courtWidth / 2);
|
||||
scene.add(net);
|
||||
|
||||
// Net poles at both ends of the net (Z=0 and Z=courtWidth)
|
||||
const poleGeometry = new THREE.CylinderGeometry(0.05, 0.05, netHeight, 8);
|
||||
const poleMaterial = new THREE.MeshStandardMaterial({ color: 0x666666 });
|
||||
|
||||
const pole1 = new THREE.Mesh(poleGeometry, poleMaterial);
|
||||
pole1.position.set(courtLength / 2, netHeight / 2, 0);
|
||||
scene.add(pole1);
|
||||
|
||||
const pole2 = new THREE.Mesh(poleGeometry, poleMaterial);
|
||||
pole2.position.set(courtLength / 2, netHeight / 2, courtWidth);
|
||||
scene.add(pole2);
|
||||
|
||||
// Ball (sphere)
|
||||
let ballMesh = null;
|
||||
let ballShadow = null;
|
||||
let ballLine = null;
|
||||
|
||||
function createBall() {
|
||||
// Remove old ball if exists
|
||||
if (ballMesh) scene.remove(ballMesh);
|
||||
if (ballShadow) scene.remove(ballShadow);
|
||||
if (ballLine) scene.remove(ballLine);
|
||||
|
||||
// Create ball
|
||||
const ballGeometry = new THREE.SphereGeometry(0.074 / 2, 32, 32);
|
||||
const ballMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0xffff00,
|
||||
emissive: 0xff4444,
|
||||
emissiveIntensity: 0.3,
|
||||
metalness: 0.5,
|
||||
roughness: 0.3
|
||||
});
|
||||
ballMesh = new THREE.Mesh(ballGeometry, ballMaterial);
|
||||
|
||||
// Shadow (circle on ground)
|
||||
const shadowGeometry = new THREE.CircleGeometry(0.1, 32);
|
||||
const shadowMaterial = new THREE.MeshBasicMaterial({
|
||||
color: 0x000000,
|
||||
transparent: true,
|
||||
opacity: 0.3,
|
||||
side: THREE.DoubleSide
|
||||
});
|
||||
ballShadow = new THREE.Mesh(shadowGeometry, shadowMaterial);
|
||||
ballShadow.rotation.x = -Math.PI / 2;
|
||||
|
||||
scene.add(ballMesh);
|
||||
scene.add(ballShadow);
|
||||
}
|
||||
|
||||
function updateBall(x, y, z) {
|
||||
if (!ballMesh) createBall();
|
||||
|
||||
ballMesh.position.set(x, z, y);
|
||||
ballShadow.position.set(x, 0.01, y);
|
||||
|
||||
// Draw line from shadow to ball if in air
|
||||
if (z > 0.1) {
|
||||
if (ballLine) scene.remove(ballLine);
|
||||
|
||||
const lineMaterial = new THREE.LineBasicMaterial({
|
||||
color: 0xffffff,
|
||||
transparent: true,
|
||||
opacity: 0.3
|
||||
});
|
||||
const linePoints = [
|
||||
new THREE.Vector3(x, z, y),
|
||||
new THREE.Vector3(x, 0, y)
|
||||
];
|
||||
const lineGeometry = new THREE.BufferGeometry().setFromPoints(linePoints);
|
||||
ballLine = new THREE.Line(lineGeometry, lineMaterial);
|
||||
scene.add(ballLine);
|
||||
} else {
|
||||
if (ballLine) {
|
||||
scene.remove(ballLine);
|
||||
ballLine = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse controls for camera
|
||||
let isDragging = false;
|
||||
let previousMousePosition = { x: 0, y: 0 };
|
||||
let cameraAngle = { theta: Math.PI / 4, phi: Math.PI / 3 };
|
||||
let cameraDistance = 22;
|
||||
|
||||
canvas3dContainer.addEventListener('mousedown', (e) => {
|
||||
isDragging = true;
|
||||
previousMousePosition = { x: e.clientX, y: e.clientY };
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', () => {
|
||||
isDragging = false;
|
||||
});
|
||||
|
||||
canvas3dContainer.addEventListener('mousemove', (e) => {
|
||||
if (!isDragging) return;
|
||||
|
||||
const deltaX = e.clientX - previousMousePosition.x;
|
||||
const deltaY = e.clientY - previousMousePosition.y;
|
||||
|
||||
cameraAngle.theta += deltaX * 0.01;
|
||||
cameraAngle.phi = Math.max(0.1, Math.min(Math.PI / 2 - 0.1, cameraAngle.phi - deltaY * 0.01));
|
||||
|
||||
previousMousePosition = { x: e.clientX, y: e.clientY };
|
||||
|
||||
updateCameraPosition();
|
||||
});
|
||||
|
||||
canvas3dContainer.addEventListener('wheel', (e) => {
|
||||
e.preventDefault();
|
||||
cameraDistance += e.deltaY * 0.01;
|
||||
cameraDistance = Math.max(5, Math.min(50, cameraDistance));
|
||||
updateCameraPosition();
|
||||
});
|
||||
|
||||
function updateCameraPosition() {
|
||||
const centerX = courtLength / 2;
|
||||
const centerZ = courtWidth / 2;
|
||||
|
||||
camera.position.x = centerX + cameraDistance * Math.sin(cameraAngle.phi) * Math.cos(cameraAngle.theta);
|
||||
camera.position.y = cameraDistance * Math.cos(cameraAngle.phi);
|
||||
camera.position.z = centerZ + cameraDistance * Math.sin(cameraAngle.phi) * Math.sin(cameraAngle.theta);
|
||||
|
||||
camera.lookAt(centerX, 0, centerZ);
|
||||
}
|
||||
|
||||
// Handle window resize
|
||||
window.addEventListener('resize', () => {
|
||||
camera.aspect = canvas3dContainer.clientWidth / canvas3dContainer.clientHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(canvas3dContainer.clientWidth, canvas3dContainer.clientHeight);
|
||||
});
|
||||
|
||||
// Animation loop
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
animate();
|
||||
|
||||
// Render current frame
|
||||
function render() {
|
||||
if (framesData.length === 0) return;
|
||||
|
||||
const frame = framesData[currentIndex];
|
||||
|
||||
// Update image - frames are in ./frames/ directory relative to HTML
|
||||
const framePath = `frames/frame_${String(frame.frame).padStart(4, '0')}.jpg`;
|
||||
frameImage.src = framePath;
|
||||
|
||||
// Update info
|
||||
frameNum.textContent = `${currentIndex + 1} / ${framesData.length} (Frame #${frame.frame})`;
|
||||
posX.textContent = frame.x_m !== null ? frame.x_m.toFixed(2) : 'N/A';
|
||||
posY.textContent = frame.y_m !== null ? frame.y_m.toFixed(2) : 'N/A';
|
||||
posZ.textContent = frame.z_m !== null ? frame.z_m.toFixed(2) : 'N/A';
|
||||
confidence.textContent = frame.confidence.toFixed(2);
|
||||
onGround.textContent = frame.on_ground ? '✓ Yes' : '✗ No';
|
||||
|
||||
// Update slider
|
||||
frameSlider.value = currentIndex;
|
||||
|
||||
// Update buttons
|
||||
prevBtn.disabled = currentIndex === 0;
|
||||
nextBtn.disabled = currentIndex === framesData.length - 1;
|
||||
|
||||
// Update ball position in 3D
|
||||
if (frame.x_m !== null && frame.y_m !== null && frame.z_m !== null) {
|
||||
updateBall(frame.x_m, frame.y_m, frame.z_m);
|
||||
}
|
||||
}
|
||||
|
||||
// Navigation functions
|
||||
function nextFrame() {
|
||||
if (currentIndex < framesData.length - 1) {
|
||||
currentIndex++;
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
function prevFrame() {
|
||||
if (currentIndex > 0) {
|
||||
currentIndex--;
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
function gotoFrame(index) {
|
||||
currentIndex = Math.max(0, Math.min(index, framesData.length - 1));
|
||||
render();
|
||||
}
|
||||
|
||||
function togglePlay() {
|
||||
if (isPlaying) {
|
||||
clearInterval(playInterval);
|
||||
isPlaying = false;
|
||||
playBtn.textContent = '▶ Play';
|
||||
} else {
|
||||
isPlaying = true;
|
||||
playBtn.textContent = '⏸ Pause';
|
||||
playInterval = setInterval(() => {
|
||||
if (currentIndex < framesData.length - 1) {
|
||||
nextFrame();
|
||||
} else {
|
||||
clearInterval(playInterval);
|
||||
isPlaying = false;
|
||||
playBtn.textContent = '▶ Play';
|
||||
currentIndex = 0;
|
||||
render();
|
||||
}
|
||||
}, 100); // 10 fps
|
||||
}
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
prevBtn.addEventListener('click', prevFrame);
|
||||
nextBtn.addEventListener('click', nextFrame);
|
||||
playBtn.addEventListener('click', togglePlay);
|
||||
frameSlider.addEventListener('input', (e) => gotoFrame(parseInt(e.target.value)));
|
||||
|
||||
// Keyboard shortcuts
|
||||
document.addEventListener('keydown', (e) => {
|
||||
switch(e.key) {
|
||||
case 'ArrowLeft':
|
||||
prevFrame();
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
nextFrame();
|
||||
break;
|
||||
case ' ':
|
||||
e.preventDefault();
|
||||
togglePlay();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Initial render
|
||||
render();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||