YuqianFu commited on
Commit
6495ab5
·
verified ·
1 Parent(s): 9aae978

Upload 22 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,23 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ videos/basketball/ball_ego_query_mask.mp4 filter=lfs diff=lfs merge=lfs -text
37
+ videos/basketball/ball_exo_target_mask.mp4 filter=lfs diff=lfs merge=lfs -text
38
+ videos/basketball/basketball_ego_original.mp4 filter=lfs diff=lfs merge=lfs -text
39
+ videos/basketball/basketball_exo_original.mp4 filter=lfs diff=lfs merge=lfs -text
40
+ videos/basketball/hoop_ego_query_mask.mp4 filter=lfs diff=lfs merge=lfs -text
41
+ videos/basketball/hoop_exo_target_mask.mp4 filter=lfs diff=lfs merge=lfs -text
42
+ videos/cooking/food_ego_query_mask.mp4 filter=lfs diff=lfs merge=lfs -text
43
+ videos/cooking/food_exo_target_mask.mp4 filter=lfs diff=lfs merge=lfs -text
44
+ videos/cooking/kitchen_ego_original.mp4 filter=lfs diff=lfs merge=lfs -text
45
+ videos/cooking/kitchen_exo_original.mp4 filter=lfs diff=lfs merge=lfs -text
46
+ videos/cooking/knife_block_ego_query_mask.mp4 filter=lfs diff=lfs merge=lfs -text
47
+ videos/cooking/knife_block_exo_target_mask.mp4 filter=lfs diff=lfs merge=lfs -text
48
+ videos/health/health_ego_original.mp4 filter=lfs diff=lfs merge=lfs -text
49
+ videos/health/health_exo_original.mp4 filter=lfs diff=lfs merge=lfs -text
50
+ videos/health/instruction_manual_ego_query_mask.mp4 filter=lfs diff=lfs merge=lfs -text
51
+ videos/health/instruction_manual_exo_target_mask.mp4 filter=lfs diff=lfs merge=lfs -text
52
+ videos/health/test_strip_ego_query_mask.mp4 filter=lfs diff=lfs merge=lfs -text
53
+ videos/health/test_strip_exo_target_mask.mp4 filter=lfs diff=lfs merge=lfs -text
54
+ videos/health/transport_box_ego_query_mask.mp4 filter=lfs diff=lfs merge=lfs -text
55
+ videos/health/transport_box_exo_target_mask.mp4 filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+
4
+ # 配置视频文件路径和场景信息
5
+ SCENES = {
6
+ "basketball": {
7
+ "ego_query": "videos/basketball/basketball_ego_original.mp4",
8
+ "exo_target": "videos/basketball/basketball_exo_original.mp4",
9
+ "objects": ["ball", "hoop"]
10
+ },
11
+ "cooking": {
12
+ "ego_query": "videos/cooking/kitchen_ego_original.mp4",
13
+ "exo_target": "videos/cooking/kitchen_exo_original.mp4",
14
+ "objects": ["food", "knife_block"]
15
+ },
16
+ "health": {
17
+ "ego_query": "videos/health/health_ego_original.mp4",
18
+ "exo_target": "videos/health/health_exo_original.mp4",
19
+ "objects": ["instruction_manual", "transport_box", "test_strip"]
20
+ }
21
+ }
22
+
23
+ def update_scene(scene):
24
+ """更新场景时的回调函数"""
25
+ ego_video = SCENES[scene]["ego_query"]
26
+ exo_video = SCENES[scene]["exo_target"]
27
+ objects = SCENES[scene]["objects"]
28
+
29
+ # 更新物体选择下拉菜单
30
+ object_dropdown = gr.Dropdown(
31
+ choices=objects,
32
+ value=None,
33
+ label="Select Object",
34
+ interactive=True
35
+ )
36
+
37
+ return ego_video, exo_video, object_dropdown
38
+
39
+ def update_videos_with_object(scene, selected_object):
40
+ """选择物体时更新视频"""
41
+ if selected_object is None:
42
+ # 如果没有选择物体,返回原始视频
43
+ ego_video = SCENES[scene]["ego_query"]
44
+ exo_video = SCENES[scene]["exo_target"]
45
+ else:
46
+ # 这里假设有mask视频的命名规则
47
+ # 例如:ball_ego_query_mask.mp4, ball_exo_target_mask.mp4
48
+ ego_video = f"videos/{scene}/{selected_object}_ego_query_mask.mp4"
49
+ exo_video = f"videos/{scene}/{selected_object}_exo_target_mask.mp4"
50
+
51
+ # 如果mask视频不存在,回退到原始视频
52
+ if not os.path.exists(ego_video):
53
+ ego_video = SCENES[scene]["ego_query"]
54
+ if not os.path.exists(exo_video):
55
+ exo_video = SCENES[scene]["exo_target"]
56
+
57
+ # 返回视频路径
58
+ return ego_video, exo_video
59
+
60
+ def sync_video_playback():
61
+ """JavaScript代码:检测两个视频都加载完毕后同步播放"""
62
+ return """
63
+ () => {
64
+ const egoVideo = document.querySelector('#ego_video video');
65
+ const exoVideo = document.querySelector('#exo_video video');
66
+
67
+ if (!egoVideo || !exoVideo) {
68
+ setTimeout(() => {
69
+ const egoVideo = document.querySelector('#ego_video video');
70
+ const exoVideo = document.querySelector('#exo_video video');
71
+ if (egoVideo && exoVideo) {
72
+ let egoLoaded = false;
73
+ let exoLoaded = false;
74
+
75
+ const checkBothLoaded = () => {
76
+ if (egoLoaded && exoLoaded) {
77
+ egoVideo.currentTime = 0;
78
+ exoVideo.currentTime = 0;
79
+ Promise.all([egoVideo.play(), exoVideo.play()]).then(() => {
80
+ console.log('Both videos started playing synchronously');
81
+ }).catch(error => console.error('Error playing videos:', error));
82
+ }
83
+ };
84
+
85
+ const onEgoLoaded = () => { egoLoaded = true; checkBothLoaded(); };
86
+ const onExoLoaded = () => { exoLoaded = true; checkBothLoaded(); };
87
+
88
+ egoVideo.addEventListener('loadeddata', onEgoLoaded, { once: true });
89
+ exoVideo.addEventListener('loadeddata', onExoLoaded, { once: true });
90
+
91
+ if (egoVideo.readyState >= 2) onEgoLoaded();
92
+ if (exoVideo.readyState >= 2) onExoLoaded();
93
+ }
94
+ }, 100);
95
+ return;
96
+ }
97
+
98
+ let egoLoaded = false;
99
+ let exoLoaded = false;
100
+
101
+ const checkBothLoaded = () => {
102
+ if (egoLoaded && exoLoaded) {
103
+ egoVideo.currentTime = 0;
104
+ exoVideo.currentTime = 0;
105
+ Promise.all([egoVideo.play(), exoVideo.play()]).then(() => {
106
+ console.log('Both videos started playing synchronously');
107
+ }).catch(error => console.error('Error playing videos:', error));
108
+ }
109
+ };
110
+
111
+ const onEgoLoaded = () => { egoLoaded = true; checkBothLoaded(); };
112
+ const onExoLoaded = () => { exoLoaded = true; checkBothLoaded(); };
113
+
114
+ egoVideo.addEventListener('loadeddata', onEgoLoaded, { once: true });
115
+ exoVideo.addEventListener('loadeddata', onExoLoaded, { once: true });
116
+
117
+ if (egoVideo.readyState >= 2) onEgoLoaded();
118
+ if (exoVideo.readyState >= 2) onExoLoaded();
119
+ }
120
+ """
121
+
122
+ def clear_loading_message():
123
+ """清除加载消息"""
124
+ return ""
125
+
126
+ # 创建 Gradio 界面
127
+ with gr.Blocks(title="ObjectRelator", theme=gr.themes.Soft()) as demo:
128
+ # 标题
129
+ gr.Markdown("""
130
+ <div style="text-align: center; margin-bottom: 30px;">
131
+ <h1 style="font-size: 3em; color: #2c3e50; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.1);">
132
+ ✨ ObjectRelator ✨
133
+ </h1>
134
+ <h2 style="font-size: 1.2em; color: #7f8c8d; margin: 10px 0; font-weight: 300;">
135
+ 👤 Enabling Cross-View Object Relation Understanding Across Ego-Centric and Exo-Centric Perspectives 📹
136
+ </h2>
137
+ </div>
138
+ """, elem_id="title")
139
+
140
+
141
+ # 控制面板
142
+ with gr.Row(elem_id="control_panel"):
143
+ with gr.Column(scale=1):
144
+ scene_dropdown = gr.Dropdown(
145
+ choices=list(SCENES.keys()),
146
+ value="basketball",
147
+ label="Select Scene",
148
+ interactive=True,
149
+ elem_id="scene_dropdown"
150
+ )
151
+
152
+ with gr.Column(scale=1):
153
+ object_dropdown = gr.Dropdown(
154
+ choices=SCENES["basketball"]["objects"],
155
+ value=None,
156
+ label="Select Object",
157
+ interactive=True,
158
+ elem_id="object_dropdown"
159
+ )
160
+
161
+ # 视频显示区域
162
+ with gr.Row(elem_id="video_container"):
163
+ with gr.Column():
164
+ gr.Markdown("""
165
+ <div style="text-align: center; margin-bottom: 15px;">
166
+ <h3 style="color: #34495e; margin: 0; display: flex; align-items: center; justify-content: center;">
167
+ <span style="margin-right: 8px;">👤</span>
168
+ Ego View
169
+ <span style="margin-left: 8px;"></span>
170
+ </h3>
171
+ </div>
172
+ """)
173
+ ego_video = gr.Video(
174
+ value=SCENES["basketball"]["ego_query"],
175
+ autoplay=False,
176
+ loop=True,
177
+ show_download_button=False,
178
+ show_share_button=False,
179
+ elem_id="ego_video"
180
+ )
181
+
182
+ with gr.Column():
183
+ gr.Markdown("""
184
+ <div style="text-align: center; margin-bottom: 15px;">
185
+ <h3 style="color: #34495e; margin: 0; display: flex; align-items: center; justify-content: center;">
186
+ <span style="margin-right: 8px;">📹</span>
187
+ Exo View
188
+ <span style="margin-left: 8px;"></span>
189
+ </h3>
190
+ </div>
191
+ """)
192
+ exo_video = gr.Video(
193
+ value=SCENES["basketball"]["exo_target"],
194
+ autoplay=False,
195
+ loop=True,
196
+ show_download_button=False,
197
+ show_share_button=False,
198
+ elem_id="exo_video"
199
+ )
200
+
201
+ # 场景选择事件处理
202
+ scene_dropdown.change(
203
+ fn=update_scene,
204
+ inputs=[scene_dropdown],
205
+ outputs=[ego_video, exo_video, object_dropdown]
206
+ ).then(
207
+ fn=None,
208
+ js=sync_video_playback()
209
+ )
210
+
211
+ # 物体选择事件处理
212
+ object_dropdown.change(
213
+ fn=update_videos_with_object,
214
+ inputs=[scene_dropdown, object_dropdown],
215
+ outputs=[ego_video, exo_video]
216
+ ).then(
217
+ fn=None,
218
+ js=sync_video_playback()
219
+ )
220
+
221
+ # 页面加载完成后执行同步播放
222
+ demo.load(fn=None, js=sync_video_playback())
223
+
224
+ # 自定义CSS样式和初始JavaScript
225
+ demo.css = """
226
+ /* 全局样式 */
227
+ .gradio-container {
228
+ max-width: 1400px;
229
+ margin: 0 auto;
230
+ padding: 20px;
231
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
232
+ min-height: 100vh;
233
+ }
234
+
235
+ /* 主内容区域 */
236
+ .contain {
237
+ background: rgba(255, 255, 255, 0.95);
238
+ border-radius: 20px;
239
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
240
+ padding: 30px;
241
+ backdrop-filter: blur(10px);
242
+ }
243
+
244
+ /* 标题样式 */
245
+ #title {
246
+ margin-bottom: 30px;
247
+ }
248
+
249
+ /* 控制面板样式 */
250
+ #control_panel {
251
+ margin-bottom: 25px;
252
+ padding: 20px;
253
+ background: linear-gradient(145deg, #f8f9fa, #e9ecef);
254
+ border-radius: 15px;
255
+ box-shadow: inset 5px 5px 10px #d1d5db, inset -5px -5px 10px #ffffff;
256
+ }
257
+
258
+ /* 下拉菜单样式 */
259
+ #scene_dropdown, #object_dropdown {
260
+ margin: 10px;
261
+ }
262
+
263
+ .gr-dropdown {
264
+ border-radius: 10px !important;
265
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1) !important;
266
+ transition: all 0.3s ease !important;
267
+ }
268
+
269
+ .gr-dropdown:hover {
270
+ transform: translateY(-2px) !important;
271
+ box-shadow: 0 6px 12px rgba(0,0,0,0.15) !important;
272
+ }
273
+
274
+ /* 视频容器样式 */
275
+ #video_container {
276
+ gap: 30px;
277
+ margin-top: 20px;
278
+ }
279
+
280
+ /* 视频样式 */
281
+ video {
282
+ border-radius: 15px !important;
283
+ box-shadow: 0 10px 30px rgba(0,0,0,0.2) !important;
284
+ transition: all 0.3s ease !important;
285
+ border: 3px solid transparent !important;
286
+ background: linear-gradient(white, white) padding-box,
287
+ linear-gradient(45deg, #667eea, #764ba2) border-box !important;
288
+ }
289
+
290
+ video:hover {
291
+ transform: scale(1.02) !important;
292
+ box-shadow: 0 15px 40px rgba(0,0,0,0.3) !important;
293
+ }
294
+
295
+ /* 视���标题样式 */
296
+ .gr-markdown h3 {
297
+ background: linear-gradient(45deg, #667eea, #764ba2);
298
+ -webkit-background-clip: text;
299
+ -webkit-text-fill-color: transparent;
300
+ background-clip: text;
301
+ font-weight: bold;
302
+ text-shadow: none;
303
+ }
304
+
305
+ /* 响应式设计 */
306
+ @media (max-width: 768px) {
307
+ .gradio-container {
308
+ padding: 10px;
309
+ }
310
+
311
+ .contain {
312
+ padding: 20px;
313
+ }
314
+
315
+ #video_container {
316
+ flex-direction: column;
317
+ }
318
+
319
+ video {
320
+ width: 100% !important;
321
+ }
322
+ }
323
+
324
+ /* 加载动画 */
325
+ @keyframes pulse {
326
+ 0% { opacity: 1; }
327
+ 50% { opacity: 0.6; }
328
+ 100% { opacity: 1; }
329
+ }
330
+
331
+ .loading {
332
+ animation: pulse 1.5s infinite;
333
+ }
334
+
335
+ /* 按钮和交互元素的美化 */
336
+ .gr-button {
337
+ border-radius: 10px !important;
338
+ background: linear-gradient(45deg, #667eea, #764ba2) !important;
339
+ border: none !important;
340
+ color: white !important;
341
+ font-weight: 600 !important;
342
+ transition: all 0.3s ease !important;
343
+ }
344
+
345
+ .gr-button:hover {
346
+ transform: translateY(-2px) !important;
347
+ box-shadow: 0 8px 15px rgba(102, 126, 234, 0.3) !important;
348
+ }
349
+ """
350
+
351
+ if __name__ == "__main__":
352
+ demo.launch(share=True)
videos/.DS_Store ADDED
Binary file (6.15 kB). View file
 
videos/basketball/ball_ego_query_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ff2b6258cc5ff9c265a67c42daa9dd00948455c3755301c60808809e45b7f9ac
3
+ size 5690792
videos/basketball/ball_exo_target_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:df5d5952a42d0d95aaa485801d943f106154596f1304b4053edac4476114c03b
3
+ size 10937262
videos/basketball/basketball_ego_original.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8dc7b8a879d349e1e7db0b626ab07697004ea8e0433b092c438f5563df5e5b5f
3
+ size 5397991
videos/basketball/basketball_exo_original.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:223ef1dd5409bdde8342c5e84f3f129abba5cd22b328b31aadc872fd0e247433
3
+ size 10852942
videos/basketball/hoop_ego_query_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0fecd652cf280a55b77dd3bc248680109a207b978f40f2ec1b6551a7ed2a1b01
3
+ size 5432247
videos/basketball/hoop_exo_target_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7b9f8a40956396e845e2eabd03ec38a8d6f54e4e90967b66d2361839174ec9bf
3
+ size 10898747
videos/cooking/food_ego_query_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f814b3c97ad37df1cdd2cc2a8333815b31c6d94c3c06d25c0c1fb0d60453db74
3
+ size 6819692
videos/cooking/food_exo_target_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0a41d171bc30294e4ef06596ca2e034ae6adc7b431e051fe32490e239e2c408a
3
+ size 10058696
videos/cooking/kitchen_ego_original.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cdc061ba4355a1bf7b184f133b0da4cb047e0d297a2f1f0207de8e0933fd6c63
3
+ size 6599169
videos/cooking/kitchen_exo_original.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a32618c97003032d456aeb01fd2f3518aa558ab74d46f0cd68c782b2d64db0c1
3
+ size 10022559
videos/cooking/knife_block_ego_query_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c0f0a03625c52eb135c65e29d6c793f69b7d920963ed805c64b0c03dfad58fc0
3
+ size 6880984
videos/cooking/knife_block_exo_target_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fea3b201077a3211f1e9e0cfa7d19fdba0a8f13f3dde24ccf5c72f66afb287a1
3
+ size 10065925
videos/health/health_ego_original.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2c896390a5d91100dc3e72dc575e9de64ad5b84de5739744136893a8cb56aff0
3
+ size 4010932
videos/health/health_exo_original.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:464a89fe26d8a3830a8f6a9c816918d455b20110b10c9b75effe8854d1ae716e
3
+ size 12120490
videos/health/instruction_manual_ego_query_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:43366456fcc4d26d20f41b6a926c5dc6962c85cc11126c998277cae7f1ec9748
3
+ size 4096522
videos/health/instruction_manual_exo_target_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:76f482b4eff5eb7daf05f5c0119afa88e51a50a2f5f0f2b6ca1d0477adb35fe3
3
+ size 12157925
videos/health/test_strip_ego_query_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:432faabcbecea72ca6e75907fe9ca55c41ac719fec63b8b706b2963d88594b6a
3
+ size 4181790
videos/health/test_strip_exo_target_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2af17008da5c5ad05f383ad3194ae6b9b09ad90d51e9f8bcd2899941861cff78
3
+ size 12156212
videos/health/transport_box_ego_query_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:694dc52b00b3443c14a0abeb776c80621679f819cf03585f06aece10d5b9ddc2
3
+ size 4271364
videos/health/transport_box_exo_target_mask.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ff388108735a35b1512463c2c9079c5dd341e0b1dca70d21753914ac9478c4f8
3
+ size 12163569