Nihill commited on
Commit
71fb836
·
verified ·
1 Parent(s): f5a3f51

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +34 -0
  2. .gradio/certificate.pem +31 -0
  3. Demo2/.gitattributes +35 -0
  4. Demo2/README.md +12 -0
  5. Demo2/app.py +420 -0
  6. README.md +2 -8
  7. app.py +422 -0
  8. app2.py +147 -0
  9. demo.py +0 -0
  10. optical_flow/Assault002_x264.mp4 +3 -0
  11. optical_flow/Assault003_x264.mp4 +3 -0
  12. optical_flow/Assault004_x264.mp4 +3 -0
  13. optical_flow/Assault005_x264.mp4 +3 -0
  14. optical_flow/Assault006_x264.mp4 +3 -0
  15. optical_flow/Assault007_x264.mp4 +3 -0
  16. optical_flow/Assault008_x264.mp4 +3 -0
  17. optical_flow/optical_flow1.mp4 +3 -0
  18. optical_flow/optical_flow2.mp4 +3 -0
  19. optical_flow/optical_flow3.mp4 +3 -0
  20. optical_flow/optical_flow4.mp4 +3 -0
  21. optical_flow/optical_flow5.mp4 +3 -0
  22. qa/Assault001_x264.json +56 -0
  23. qa/Assault002_x264.json +56 -0
  24. qa/Assault003_x264.json +56 -0
  25. qa/Assault004_x264.json +56 -0
  26. qa/Assault005_x264.json +56 -0
  27. qa/Assault006_x264.json +56 -0
  28. qa/Assault007_x264.json +56 -0
  29. qa/Assault008_x264.json +56 -0
  30. requirements.txt +3 -0
  31. vggt/Assault002_x264.mp4 +3 -0
  32. vggt/Assault003_x264.mp4 +3 -0
  33. vggt/Assault004_x264.mp4 +3 -0
  34. vggt/Assault005_x264.mp4 +3 -0
  35. vggt/Assault006_x264.mp4 +3 -0
  36. vggt/Assault007_x264.mp4 +3 -0
  37. vggt/Assault008_x264.mp4 +3 -0
  38. video/Assault001_x264.mp4 +3 -0
  39. video/Assault002_x264.mp4 +3 -0
  40. video/Assault003_x264.mp4 +3 -0
  41. video/Assault004_x264.mp4 +3 -0
  42. video/Assault005_x264.mp4 +3 -0
  43. video/Assault006_x264.mp4 +3 -0
  44. video/Assault007_x264.mp4 +3 -0
  45. video/Assault008_x264.mp4 +3 -0
  46. vis.py +29 -0
  47. yolo/Assault002_x264.mp4 +3 -0
  48. yolo/Assault003_x264.mp4 +3 -0
  49. yolo/Assault004_x264.mp4 +3 -0
  50. yolo/Assault005_x264.mp4 +3 -0
.gitattributes CHANGED
@@ -33,3 +33,37 @@ 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
+ optical_flow/Assault002_x264.mp4 filter=lfs diff=lfs merge=lfs -text
37
+ optical_flow/Assault003_x264.mp4 filter=lfs diff=lfs merge=lfs -text
38
+ optical_flow/Assault004_x264.mp4 filter=lfs diff=lfs merge=lfs -text
39
+ optical_flow/Assault005_x264.mp4 filter=lfs diff=lfs merge=lfs -text
40
+ optical_flow/Assault006_x264.mp4 filter=lfs diff=lfs merge=lfs -text
41
+ optical_flow/Assault007_x264.mp4 filter=lfs diff=lfs merge=lfs -text
42
+ optical_flow/Assault008_x264.mp4 filter=lfs diff=lfs merge=lfs -text
43
+ optical_flow/optical_flow1.mp4 filter=lfs diff=lfs merge=lfs -text
44
+ optical_flow/optical_flow2.mp4 filter=lfs diff=lfs merge=lfs -text
45
+ optical_flow/optical_flow3.mp4 filter=lfs diff=lfs merge=lfs -text
46
+ optical_flow/optical_flow4.mp4 filter=lfs diff=lfs merge=lfs -text
47
+ optical_flow/optical_flow5.mp4 filter=lfs diff=lfs merge=lfs -text
48
+ vggt/Assault002_x264.mp4 filter=lfs diff=lfs merge=lfs -text
49
+ vggt/Assault003_x264.mp4 filter=lfs diff=lfs merge=lfs -text
50
+ vggt/Assault004_x264.mp4 filter=lfs diff=lfs merge=lfs -text
51
+ vggt/Assault005_x264.mp4 filter=lfs diff=lfs merge=lfs -text
52
+ vggt/Assault006_x264.mp4 filter=lfs diff=lfs merge=lfs -text
53
+ vggt/Assault007_x264.mp4 filter=lfs diff=lfs merge=lfs -text
54
+ vggt/Assault008_x264.mp4 filter=lfs diff=lfs merge=lfs -text
55
+ video/Assault001_x264.mp4 filter=lfs diff=lfs merge=lfs -text
56
+ video/Assault002_x264.mp4 filter=lfs diff=lfs merge=lfs -text
57
+ video/Assault003_x264.mp4 filter=lfs diff=lfs merge=lfs -text
58
+ video/Assault004_x264.mp4 filter=lfs diff=lfs merge=lfs -text
59
+ video/Assault005_x264.mp4 filter=lfs diff=lfs merge=lfs -text
60
+ video/Assault006_x264.mp4 filter=lfs diff=lfs merge=lfs -text
61
+ video/Assault007_x264.mp4 filter=lfs diff=lfs merge=lfs -text
62
+ video/Assault008_x264.mp4 filter=lfs diff=lfs merge=lfs -text
63
+ yolo/Assault002_x264.mp4 filter=lfs diff=lfs merge=lfs -text
64
+ yolo/Assault003_x264.mp4 filter=lfs diff=lfs merge=lfs -text
65
+ yolo/Assault004_x264.mp4 filter=lfs diff=lfs merge=lfs -text
66
+ yolo/Assault005_x264.mp4 filter=lfs diff=lfs merge=lfs -text
67
+ yolo/Assault006_x264.mp4 filter=lfs diff=lfs merge=lfs -text
68
+ yolo/Assault007_x264.mp4 filter=lfs diff=lfs merge=lfs -text
69
+ yolo/Assault008_x264.mp4 filter=lfs diff=lfs merge=lfs -text
.gradio/certificate.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
3
+ TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
4
+ cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
5
+ WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
6
+ ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
7
+ MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
8
+ h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
9
+ 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
10
+ A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
11
+ T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
12
+ B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
13
+ B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
14
+ KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
15
+ OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
16
+ jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
17
+ qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
18
+ rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
19
+ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
20
+ hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
21
+ ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
22
+ 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
23
+ NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
24
+ ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
25
+ TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
26
+ jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
27
+ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
28
+ 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
29
+ mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
30
+ emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
31
+ -----END CERTIFICATE-----
Demo2/.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz 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
Demo2/README.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Demo2
3
+ emoji: 🦀
4
+ colorFrom: indigo
5
+ colorTo: blue
6
+ sdk: gradio
7
+ sdk_version: 5.34.2
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
Demo2/app.py ADDED
@@ -0,0 +1,420 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import numpy as np
4
+ import plotly.graph_objects as go
5
+ import plotly.express as px
6
+ from pathlib import Path
7
+ import sys
8
+ import asyncio
9
+ import json
10
+ if sys.platform == "win32":
11
+ asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
12
+ # Get absolute paths for all files
13
+ def get_absolute_path(relative_path):
14
+ """Convert relative path to absolute path"""
15
+ return os.path.abspath(relative_path)
16
+
17
+ def check_file_exists(file_path):
18
+ """Check if file exists and return absolute path or None"""
19
+ abs_path = get_absolute_path(file_path)
20
+ if os.path.exists(abs_path):
21
+ return abs_path
22
+ else:
23
+ print(f"Warning: File not found: {file_path}")
24
+ return None
25
+
26
+ # Define the data structure with absolute paths
27
+ SAMPLES = {}
28
+ for i in range(2, 9): # Updated to handle 8 assault videos
29
+ sample_data = {
30
+ "input": f"video/Assault{i:03d}_x264.mp4", # Updated naming pattern
31
+ "optical_flow": f"optical_flow/Assault{i:03d}_x264.mp4",
32
+ "yolo": f"yolo/Assault{i:03d}_x264.mp4",
33
+ "vggt": f"vggt/Assault{i:03d}_x264.mp4",
34
+ # "pcd": f"pcd/Assault{i:03d}_x264.pcd",
35
+ "qa": f"qa/Assault{i:03d}_x264.json"
36
+ }
37
+
38
+ # Convert to absolute paths and check existence
39
+ SAMPLES[i] = {}
40
+ for key, path in sample_data.items():
41
+ abs_path = check_file_exists(path)
42
+ SAMPLES[i][key] = abs_path
43
+
44
+ def load_qa_data(qa_file):
45
+ """Load QA data from JSON file and format for chat display"""
46
+ try:
47
+ if not qa_file or not os.path.exists(qa_file):
48
+ return []
49
+
50
+ with open(qa_file, 'r', encoding='utf-8') as f:
51
+ qa_data = json.load(f)
52
+
53
+ # Format QA pairs for Gradio chat interface
54
+ chat_history = []
55
+ for qa_pair in qa_data.get('qa_pairs', []):
56
+ question = qa_pair.get('question', '')
57
+ answer = qa_pair.get('answer', '')
58
+
59
+ # Add question (user message)
60
+ chat_history.append([question, answer])
61
+
62
+ return chat_history
63
+ except Exception as e:
64
+ print(f"Error loading QA data {qa_file}: {e}")
65
+ return []
66
+
67
+ def get_qa_metadata(qa_file):
68
+ """Get metadata from QA JSON file"""
69
+ try:
70
+ if not qa_file or not os.path.exists(qa_file):
71
+ return {}
72
+
73
+ with open(qa_file, 'r', encoding='utf-8') as f:
74
+ qa_data = json.load(f)
75
+
76
+ return {
77
+ 'video_name': qa_data.get('video_name', ''),
78
+ 'timestamp': qa_data.get('timestamp', ''),
79
+ 'model_path': qa_data.get('model_path', ''),
80
+ 'max_num_frames': qa_data.get('max_num_frames', 0),
81
+ 'total_questions': len(qa_data.get('qa_pairs', []))
82
+ }
83
+ except Exception as e:
84
+ print(f"Error loading QA metadata {qa_file}: {e}")
85
+ return {}
86
+
87
+ def load_point_cloud_plotly(pcd_file):
88
+ """Load point cloud and create a 3D plotly visualization"""
89
+ try:
90
+ if not pcd_file or not os.path.exists(pcd_file):
91
+ return None
92
+
93
+ pcd = o3d.io.read_point_cloud(pcd_file)
94
+ points = np.asarray(pcd.points)
95
+ colors = np.asarray(pcd.colors) if pcd.has_colors() else None
96
+
97
+ if len(points) == 0:
98
+ return None
99
+
100
+ # Subsample points if too many (for performance)
101
+ if len(points) > 10000:
102
+ indices = np.random.choice(len(points), 10000, replace=False)
103
+ points = points[indices]
104
+ if colors is not None:
105
+ colors = colors[indices]
106
+
107
+ # Create 3D scatter plot
108
+ if colors is not None and len(colors) > 0:
109
+ # Convert colors to RGB if needed
110
+ if colors.max() <= 1.0:
111
+ colors = (colors * 255).astype(int)
112
+ color_rgb = [f'rgb({r},{g},{b})' for r, g, b in colors]
113
+
114
+ fig = go.Figure(data=[go.Scatter3d(
115
+ x=points[:, 0],
116
+ y=points[:, 1],
117
+ z=points[:, 2],
118
+ mode='markers',
119
+ marker=dict(
120
+ size=1.7,
121
+ color=color_rgb,
122
+ ),
123
+ text=[f'Point {i}' for i in range(len(points))],
124
+ hovertemplate='<b>Point %{text}</b><br>X: %{x}<br>Y: %{y}<br>Z: %{z}<extra></extra>'
125
+ )])
126
+ else:
127
+ fig = go.Figure(data=[go.Scatter3d(
128
+ x=points[:, 0],
129
+ y=points[:, 1],
130
+ z=points[:, 2],
131
+ mode='markers',
132
+ marker=dict(
133
+ size=2,
134
+ color=points[:, 2], # Color by Z coordinate
135
+ colorscale='Viridis',
136
+ showscale=True
137
+ ),
138
+ text=[f'Point {i}' for i in range(len(points))],
139
+ hovertemplate='<b>Point %{text}</b><br>X: %{x}<br>Y: %{y}<br>Z: %{z}<extra></extra>'
140
+ )])
141
+
142
+ fig.update_layout(
143
+ title=f'3D Point Cloud Visualization - {os.path.basename(pcd_file)}',
144
+ scene=dict(
145
+ xaxis_title='X',
146
+ yaxis_title='Y',
147
+ zaxis_title='Z',
148
+ camera=dict(
149
+ eye=dict(x=1.5, y=1.5, z=1.5)
150
+ ),
151
+ bgcolor='rgb(10, 10, 10)',
152
+ ),
153
+ margin=dict(l=0, r=0, t=50, b=0),
154
+ paper_bgcolor='rgb(20, 20, 20)',
155
+ plot_bgcolor='rgb(20, 20, 20)',
156
+ font=dict(color='white')
157
+ )
158
+
159
+ return fig
160
+ except Exception as e:
161
+ print(f"Error loading point cloud {pcd_file}: {e}")
162
+ return None
163
+
164
+ def create_sample_gallery(sample_id):
165
+ """Create a gallery view for a specific sample"""
166
+ sample = SAMPLES[sample_id]
167
+
168
+ # Load point cloud visualization
169
+ pcd_plot = load_point_cloud_plotly(sample["pcd"])
170
+
171
+ return (
172
+ sample["input"], # Input video
173
+ sample["optical_flow"], # Optical flow video
174
+ sample["yolo"], # YOLO video
175
+ sample["vggt"], # VGGT video
176
+ pcd_plot # Point cloud plot
177
+ )
178
+
179
+ def create_overview_gallery():
180
+ """Create an overview showing all samples"""
181
+ gallery_items = []
182
+ for i in range(1, 6):
183
+ sample = SAMPLES[i]
184
+ # Only add items that exist
185
+ if sample["input"]:
186
+ gallery_items.append((sample["input"], f"Sample {i} - Input"))
187
+ if sample["optical_flow"]:
188
+ gallery_items.append((sample["optical_flow"], f"Sample {i} - Optical Flow"))
189
+ if sample["yolo"]:
190
+ gallery_items.append((sample["yolo"], f"Sample {i} - YOLO"))
191
+ if sample["vggt"]:
192
+ gallery_items.append((sample["vggt"], f"Sample {i} - VGGT"))
193
+ return gallery_items
194
+
195
+ # Custom CSS for better styling
196
+ custom_css = """
197
+ # .gradio-container {
198
+ # max-width: 1200px !important;
199
+ # }
200
+ .gallery-item {
201
+ border-radius: 10px;
202
+ }
203
+ h1 {
204
+ text-align: center;
205
+ color: #2c3e50;
206
+ margin-bottom: 30px;
207
+ }
208
+ .tab-nav {
209
+ margin-bottom: 20px;
210
+ }
211
+ .qa-section-header {
212
+ font-size: 1.2em;
213
+ color: #2c3e50;
214
+ margin-top: 20px;
215
+ }
216
+ .qa-metadata {
217
+ background-color: #f8f9fa;
218
+ padding: 15px;
219
+ border-radius: 8px;
220
+ border-left: 4px solid #007bff;
221
+ }
222
+ .qa-info {
223
+ background-color: #e7f3ff;
224
+ padding: 10px;
225
+ border-radius: 5px;
226
+ font-style: italic;
227
+ }
228
+ """
229
+
230
+ # Create the Gradio interface
231
+ with gr.Blocks(css=custom_css, title="Anomalous Event Detection") as demo:
232
+ gr.Markdown("# 🎥 Results Gallery")
233
+
234
+ with gr.Tabs() as tabs:
235
+ # Individual sample tabs
236
+ for i in range(2, 9):
237
+ with gr.Tab(f"🎬 Sample {i-1}"):
238
+ gr.Markdown(f"## Sample {i-1} - Detailed View")
239
+
240
+ sample = SAMPLES[i]
241
+ # Top Row: Input Video + Chat History
242
+ with gr.Row():
243
+ # Left Column: Input Video (narrower)
244
+ with gr.Column(scale=1):
245
+ gr.Markdown("### 📹 Input Video")
246
+ if sample["input"]:
247
+ input_video = gr.Video(
248
+ value=sample["input"],
249
+ label="Original Input",
250
+ show_label=True
251
+ )
252
+ else:
253
+ gr.Markdown("❌ Input video not found")
254
+
255
+ # Right Column: Q&A Chat History
256
+ with gr.Column(scale=1, min_width=400):
257
+ gr.Markdown("### 💬 Q&A Chat History")
258
+
259
+ if sample["qa"]:
260
+ # Load QA metadata
261
+ qa_metadata = get_qa_metadata(sample["qa"])
262
+ if qa_metadata:
263
+ gr.Markdown(f"""
264
+ **📊 Chat Session Info:**
265
+ - **Video:** {qa_metadata.get('video_name', 'N/A')}
266
+ - **Total Questions:** {qa_metadata.get('total_questions', 0)}
267
+ - **Max Frames:** {qa_metadata.get('max_num_frames', 0)}
268
+ - **Timestamp:** {qa_metadata.get('timestamp', 'N/A')[:19].replace('T', ' ')}
269
+ """)
270
+
271
+ # Load and display chat history
272
+ qa_history = load_qa_data(sample["qa"])
273
+ if qa_history:
274
+ chatbot = gr.Chatbot(
275
+ value=qa_history,
276
+ label="Video Analysis Q&A",
277
+ show_label=True,
278
+ height=500,
279
+ avatar_images=["👤", "🤖"]
280
+ )
281
+
282
+ gr.Markdown("""
283
+ 💡 **About this Q&A:** Questions asked by humans about the video content and answers from an AI model trained for video analysis.
284
+ """)
285
+ else:
286
+ gr.Markdown("❌ No Q&A data available for this sample")
287
+ else:
288
+ gr.Markdown("❌ Q&A file not found for this sample")
289
+ # VGGT and Point Cloud in a row
290
+ with gr.Row():
291
+ with gr.Column():
292
+ gr.Markdown("### 🎮 VGGT")
293
+
294
+ if sample["vggt"]:
295
+ vggt_video = gr.Video(
296
+ value=sample["vggt"],
297
+ label="VGGT Processing",
298
+ show_label=True
299
+ )
300
+ else:
301
+ gr.Markdown("❌ VGGT video not found")
302
+
303
+ with gr.Column():
304
+ pass
305
+ # gr.Markdown("### ☁️ 3D Point Cloud")
306
+
307
+ # if sample["pcd"]:
308
+ # try:
309
+ # pcd_plot = gr.Plot(
310
+ # value=load_point_cloud_plotly(sample["pcd"]),
311
+ # label="Interactive 3D Point Cloud",
312
+ # show_label=True
313
+ # )
314
+ # except Exception as e:
315
+ # gr.Markdown(f"❌ Error loading point cloud: {str(e)}")
316
+ # else:
317
+ # gr.Markdown("❌ Point cloud file not found")
318
+
319
+
320
+
321
+ # Bottom Section: Other Analysis Results
322
+ with gr.Row():
323
+ with gr.Column(scale=2):
324
+ # Optical Flow and YOLO in a row
325
+ with gr.Row():
326
+ with gr.Column():
327
+ gr.Markdown("### 🌊 Optical Flow")
328
+ if sample["optical_flow"]:
329
+ optical_flow_video = gr.Video(
330
+ value=sample["optical_flow"],
331
+ label="Motion Analysis",
332
+ show_label=True
333
+ )
334
+ else:
335
+ gr.Markdown("❌ Optical flow video not found")
336
+
337
+ with gr.Column():
338
+ gr.Markdown("### 🎯 YOLO Detection")
339
+ if sample["yolo"]:
340
+ yolo_video = gr.Video(
341
+ value=sample["yolo"],
342
+ label="Object Detection",
343
+ show_label=True
344
+ )
345
+ else:
346
+ gr.Markdown("❌ YOLO video not found")
347
+
348
+
349
+ # Comparison tab
350
+ # with gr.Tab("🔍 Compare"):
351
+ # gr.Markdown("## Compare Different Samples")
352
+ # gr.Markdown("Select two samples to compare side by side")
353
+
354
+ # with gr.Row():
355
+ # sample1_dropdown = gr.Dropdown(
356
+ # choices=list(range(1, 6)),
357
+ # value=1,
358
+ # label="Sample 1"
359
+ # )
360
+ # sample2_dropdown = gr.Dropdown(
361
+ # choices=list(range(1, 6)),
362
+ # value=2,
363
+ # label="Sample 2"
364
+ # )
365
+
366
+ # with gr.Row():
367
+ # with gr.Column():
368
+ # gr.Markdown("### Sample 1")
369
+ # comp_input1 = gr.Video(label="Input")
370
+ # comp_optical1 = gr.Video(label="Optical Flow")
371
+ # comp_yolo1 = gr.Video(label="YOLO")
372
+ # comp_vggt1 = gr.Video(label="VGGT")
373
+ # comp_pcd1 = gr.Plot(label="Point Cloud")
374
+
375
+ # with gr.Column():
376
+ # gr.Markdown("### Sample 2")
377
+ # comp_input2 = gr.Video(label="Input")
378
+ # comp_optical2 = gr.Video(label="Optical Flow")
379
+ # comp_yolo2 = gr.Video(label="YOLO")
380
+ # comp_vggt2 = gr.Video(label="VGGT")
381
+ # comp_pcd2 = gr.Plot(label="Point Cloud")
382
+
383
+ # # Update comparison when dropdowns change
384
+ # def update_comparison(sample1_id, sample2_id):
385
+ # try:
386
+ # sample1_results = create_sample_gallery(sample1_id)
387
+ # sample2_results = create_sample_gallery(sample2_id)
388
+ # return sample1_results + sample2_results
389
+ # except Exception as e:
390
+ # print(f"Error updating comparison: {e}")
391
+ # return [None] * 10
392
+
393
+ # for dropdown in [sample1_dropdown, sample2_dropdown]:
394
+ # dropdown.change(
395
+ # update_comparison,
396
+ # inputs=[sample1_dropdown, sample2_dropdown],
397
+ # outputs=[
398
+ # comp_input1, comp_optical1, comp_yolo1, comp_vggt1, comp_pcd1,
399
+ # comp_input2, comp_optical2, comp_yolo2, comp_vggt2, comp_pcd2
400
+ # ]
401
+ # )
402
+
403
+
404
+ if __name__ == "__main__":
405
+ # Print file status for debugging
406
+ print("=== File Status Check ===")
407
+ for i in range(2, 9):
408
+ print(f"\nSample {i}:")
409
+ for key, path in SAMPLES[i].items():
410
+ status = "✅ Found" if path else "❌ Missing"
411
+ print(f" {key}: {status}")
412
+
413
+ print(f"\n=== Starting Gradio App ===")
414
+ demo.launch(
415
+ share=True,
416
+ server_name="127.0.0.1",
417
+ server_port=7861,
418
+ show_error=True,
419
+ inbrowser=True
420
+ )
README.md CHANGED
@@ -1,12 +1,6 @@
1
  ---
2
- title: Demo
3
- emoji: 📈
4
- colorFrom: green
5
- colorTo: blue
6
  sdk: gradio
7
  sdk_version: 5.34.2
8
- app_file: app.py
9
- pinned: false
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: demo
3
+ app_file: app.py
 
 
4
  sdk: gradio
5
  sdk_version: 5.34.2
 
 
6
  ---
 
 
app.py ADDED
@@ -0,0 +1,422 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import open3d as o3d
4
+ import numpy as np
5
+ import plotly.graph_objects as go
6
+ import plotly.express as px
7
+ from pathlib import Path
8
+ import sys
9
+ import asyncio
10
+ import json
11
+ if sys.platform == "win32":
12
+ asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
13
+
14
+ # Get absolute paths for all files
15
+ def get_absolute_path(relative_path):
16
+ """Convert relative path to absolute path"""
17
+ return os.path.abspath(relative_path)
18
+
19
+ def check_file_exists(file_path):
20
+ """Check if file exists and return absolute path or None"""
21
+ abs_path = get_absolute_path(file_path)
22
+ if os.path.exists(abs_path):
23
+ return abs_path
24
+ else:
25
+ print(f"Warning: File not found: {file_path}")
26
+ return None
27
+
28
+ # Define the data structure with absolute paths
29
+ SAMPLES = {}
30
+ for i in range(2, 9): # Updated to handle 8 assault videos
31
+ sample_data = {
32
+ "input": f"video/Assault{i:03d}_x264.mp4", # Updated naming pattern
33
+ "optical_flow": f"optical_flow/Assault{i:03d}_x264.mp4",
34
+ "yolo": f"yolo/Assault{i:03d}_x264.mp4",
35
+ "vggt": f"vggt/Assault{i:03d}_x264.mp4",
36
+ # "pcd": f"pcd/Assault{i:03d}_x264.pcd",
37
+ "qa": f"qa/Assault{i:03d}_x264.json"
38
+ }
39
+
40
+ # Convert to absolute paths and check existence
41
+ SAMPLES[i] = {}
42
+ for key, path in sample_data.items():
43
+ abs_path = check_file_exists(path)
44
+ SAMPLES[i][key] = abs_path
45
+
46
+ def load_qa_data(qa_file):
47
+ """Load QA data from JSON file and format for chat display"""
48
+ try:
49
+ if not qa_file or not os.path.exists(qa_file):
50
+ return []
51
+
52
+ with open(qa_file, 'r', encoding='utf-8') as f:
53
+ qa_data = json.load(f)
54
+
55
+ # Format QA pairs for Gradio chat interface
56
+ chat_history = []
57
+ for qa_pair in qa_data.get('qa_pairs', []):
58
+ question = qa_pair.get('question', '')
59
+ answer = qa_pair.get('answer', '')
60
+
61
+ # Add question (user message)
62
+ chat_history.append([question, answer])
63
+
64
+ return chat_history
65
+ except Exception as e:
66
+ print(f"Error loading QA data {qa_file}: {e}")
67
+ return []
68
+
69
+ def get_qa_metadata(qa_file):
70
+ """Get metadata from QA JSON file"""
71
+ try:
72
+ if not qa_file or not os.path.exists(qa_file):
73
+ return {}
74
+
75
+ with open(qa_file, 'r', encoding='utf-8') as f:
76
+ qa_data = json.load(f)
77
+
78
+ return {
79
+ 'video_name': qa_data.get('video_name', ''),
80
+ 'timestamp': qa_data.get('timestamp', ''),
81
+ 'model_path': qa_data.get('model_path', ''),
82
+ 'max_num_frames': qa_data.get('max_num_frames', 0),
83
+ 'total_questions': len(qa_data.get('qa_pairs', []))
84
+ }
85
+ except Exception as e:
86
+ print(f"Error loading QA metadata {qa_file}: {e}")
87
+ return {}
88
+
89
+ def load_point_cloud_plotly(pcd_file):
90
+ """Load point cloud and create a 3D plotly visualization"""
91
+ try:
92
+ if not pcd_file or not os.path.exists(pcd_file):
93
+ return None
94
+
95
+ pcd = o3d.io.read_point_cloud(pcd_file)
96
+ points = np.asarray(pcd.points)
97
+ colors = np.asarray(pcd.colors) if pcd.has_colors() else None
98
+
99
+ if len(points) == 0:
100
+ return None
101
+
102
+ # Subsample points if too many (for performance)
103
+ if len(points) > 10000:
104
+ indices = np.random.choice(len(points), 10000, replace=False)
105
+ points = points[indices]
106
+ if colors is not None:
107
+ colors = colors[indices]
108
+
109
+ # Create 3D scatter plot
110
+ if colors is not None and len(colors) > 0:
111
+ # Convert colors to RGB if needed
112
+ if colors.max() <= 1.0:
113
+ colors = (colors * 255).astype(int)
114
+ color_rgb = [f'rgb({r},{g},{b})' for r, g, b in colors]
115
+
116
+ fig = go.Figure(data=[go.Scatter3d(
117
+ x=points[:, 0],
118
+ y=points[:, 1],
119
+ z=points[:, 2],
120
+ mode='markers',
121
+ marker=dict(
122
+ size=1.7,
123
+ color=color_rgb,
124
+ ),
125
+ text=[f'Point {i}' for i in range(len(points))],
126
+ hovertemplate='<b>Point %{text}</b><br>X: %{x}<br>Y: %{y}<br>Z: %{z}<extra></extra>'
127
+ )])
128
+ else:
129
+ fig = go.Figure(data=[go.Scatter3d(
130
+ x=points[:, 0],
131
+ y=points[:, 1],
132
+ z=points[:, 2],
133
+ mode='markers',
134
+ marker=dict(
135
+ size=2,
136
+ color=points[:, 2], # Color by Z coordinate
137
+ colorscale='Viridis',
138
+ showscale=True
139
+ ),
140
+ text=[f'Point {i}' for i in range(len(points))],
141
+ hovertemplate='<b>Point %{text}</b><br>X: %{x}<br>Y: %{y}<br>Z: %{z}<extra></extra>'
142
+ )])
143
+
144
+ fig.update_layout(
145
+ title=f'3D Point Cloud Visualization - {os.path.basename(pcd_file)}',
146
+ scene=dict(
147
+ xaxis_title='X',
148
+ yaxis_title='Y',
149
+ zaxis_title='Z',
150
+ camera=dict(
151
+ eye=dict(x=1.5, y=1.5, z=1.5)
152
+ ),
153
+ bgcolor='rgb(10, 10, 10)',
154
+ ),
155
+ margin=dict(l=0, r=0, t=50, b=0),
156
+ paper_bgcolor='rgb(20, 20, 20)',
157
+ plot_bgcolor='rgb(20, 20, 20)',
158
+ font=dict(color='white')
159
+ )
160
+
161
+ return fig
162
+ except Exception as e:
163
+ print(f"Error loading point cloud {pcd_file}: {e}")
164
+ return None
165
+
166
+ def create_sample_gallery(sample_id):
167
+ """Create a gallery view for a specific sample"""
168
+ sample = SAMPLES[sample_id]
169
+
170
+ # Load point cloud visualization
171
+ pcd_plot = load_point_cloud_plotly(sample["pcd"])
172
+
173
+ return (
174
+ sample["input"], # Input video
175
+ sample["optical_flow"], # Optical flow video
176
+ sample["yolo"], # YOLO video
177
+ sample["vggt"], # VGGT video
178
+ pcd_plot # Point cloud plot
179
+ )
180
+
181
+ def create_overview_gallery():
182
+ """Create an overview showing all samples"""
183
+ gallery_items = []
184
+ for i in range(1, 6):
185
+ sample = SAMPLES[i]
186
+ # Only add items that exist
187
+ if sample["input"]:
188
+ gallery_items.append((sample["input"], f"Sample {i} - Input"))
189
+ if sample["optical_flow"]:
190
+ gallery_items.append((sample["optical_flow"], f"Sample {i} - Optical Flow"))
191
+ if sample["yolo"]:
192
+ gallery_items.append((sample["yolo"], f"Sample {i} - YOLO"))
193
+ if sample["vggt"]:
194
+ gallery_items.append((sample["vggt"], f"Sample {i} - VGGT"))
195
+ return gallery_items
196
+
197
+ # Custom CSS for better styling
198
+ custom_css = """
199
+ # .gradio-container {
200
+ # max-width: 1200px !important;
201
+ # }
202
+ .gallery-item {
203
+ border-radius: 10px;
204
+ }
205
+ h1 {
206
+ text-align: center;
207
+ color: #2c3e50;
208
+ margin-bottom: 30px;
209
+ }
210
+ .tab-nav {
211
+ margin-bottom: 20px;
212
+ }
213
+ .qa-section-header {
214
+ font-size: 1.2em;
215
+ color: #2c3e50;
216
+ margin-top: 20px;
217
+ }
218
+ .qa-metadata {
219
+ background-color: #f8f9fa;
220
+ padding: 15px;
221
+ border-radius: 8px;
222
+ border-left: 4px solid #007bff;
223
+ }
224
+ .qa-info {
225
+ background-color: #e7f3ff;
226
+ padding: 10px;
227
+ border-radius: 5px;
228
+ font-style: italic;
229
+ }
230
+ """
231
+
232
+ # Create the Gradio interface
233
+ with gr.Blocks(css=custom_css, title="Anomalous Event Detection") as demo:
234
+ gr.Markdown("# 🎥 Results Gallery")
235
+
236
+ with gr.Tabs() as tabs:
237
+ # Individual sample tabs
238
+ for i in range(2, 9):
239
+ with gr.Tab(f"🎬 Sample {i-1}"):
240
+ gr.Markdown(f"## Sample {i-1} - Detailed View")
241
+
242
+ sample = SAMPLES[i]
243
+ # Top Row: Input Video + Chat History
244
+ with gr.Row():
245
+ # Left Column: Input Video (narrower)
246
+ with gr.Column(scale=1):
247
+ gr.Markdown("### 📹 Input Video")
248
+ if sample["input"]:
249
+ input_video = gr.Video(
250
+ value=sample["input"],
251
+ label="Original Input",
252
+ show_label=True
253
+ )
254
+ else:
255
+ gr.Markdown("❌ Input video not found")
256
+
257
+ # Right Column: Q&A Chat History
258
+ with gr.Column(scale=1, min_width=400):
259
+ gr.Markdown("### 💬 Q&A Chat History")
260
+
261
+ if sample["qa"]:
262
+ # Load QA metadata
263
+ qa_metadata = get_qa_metadata(sample["qa"])
264
+ if qa_metadata:
265
+ gr.Markdown(f"""
266
+ **📊 Chat Session Info:**
267
+ - **Video:** {qa_metadata.get('video_name', 'N/A')}
268
+ - **Total Questions:** {qa_metadata.get('total_questions', 0)}
269
+ - **Max Frames:** {qa_metadata.get('max_num_frames', 0)}
270
+ - **Timestamp:** {qa_metadata.get('timestamp', 'N/A')[:19].replace('T', ' ')}
271
+ """)
272
+
273
+ # Load and display chat history
274
+ qa_history = load_qa_data(sample["qa"])
275
+ if qa_history:
276
+ chatbot = gr.Chatbot(
277
+ value=qa_history,
278
+ label="Video Analysis Q&A",
279
+ show_label=True,
280
+ height=500,
281
+ avatar_images=["���", "🤖"]
282
+ )
283
+
284
+ gr.Markdown("""
285
+ 💡 **About this Q&A:** Questions asked by humans about the video content and answers from an AI model trained for video analysis.
286
+ """)
287
+ else:
288
+ gr.Markdown("❌ No Q&A data available for this sample")
289
+ else:
290
+ gr.Markdown("❌ Q&A file not found for this sample")
291
+ # VGGT and Point Cloud in a row
292
+ with gr.Row():
293
+ with gr.Column():
294
+ gr.Markdown("### 🎮 VGGT")
295
+
296
+ if sample["vggt"]:
297
+ vggt_video = gr.Video(
298
+ value=sample["vggt"],
299
+ label="VGGT Processing",
300
+ show_label=True
301
+ )
302
+ else:
303
+ gr.Markdown("❌ VGGT video not found")
304
+
305
+ with gr.Column():
306
+ pass
307
+ # gr.Markdown("### ☁️ 3D Point Cloud")
308
+
309
+ # if sample["pcd"]:
310
+ # try:
311
+ # pcd_plot = gr.Plot(
312
+ # value=load_point_cloud_plotly(sample["pcd"]),
313
+ # label="Interactive 3D Point Cloud",
314
+ # show_label=True
315
+ # )
316
+ # except Exception as e:
317
+ # gr.Markdown(f"❌ Error loading point cloud: {str(e)}")
318
+ # else:
319
+ # gr.Markdown("❌ Point cloud file not found")
320
+
321
+
322
+
323
+ # Bottom Section: Other Analysis Results
324
+ with gr.Row():
325
+ with gr.Column(scale=2):
326
+ # Optical Flow and YOLO in a row
327
+ with gr.Row():
328
+ with gr.Column():
329
+ gr.Markdown("### 🌊 Optical Flow")
330
+ if sample["optical_flow"]:
331
+ optical_flow_video = gr.Video(
332
+ value=sample["optical_flow"],
333
+ label="Motion Analysis",
334
+ show_label=True
335
+ )
336
+ else:
337
+ gr.Markdown("❌ Optical flow video not found")
338
+
339
+ with gr.Column():
340
+ gr.Markdown("### 🎯 YOLO Detection")
341
+ if sample["yolo"]:
342
+ yolo_video = gr.Video(
343
+ value=sample["yolo"],
344
+ label="Object Detection",
345
+ show_label=True
346
+ )
347
+ else:
348
+ gr.Markdown("❌ YOLO video not found")
349
+
350
+
351
+ # Comparison tab
352
+ # with gr.Tab("🔍 Compare"):
353
+ # gr.Markdown("## Compare Different Samples")
354
+ # gr.Markdown("Select two samples to compare side by side")
355
+
356
+ # with gr.Row():
357
+ # sample1_dropdown = gr.Dropdown(
358
+ # choices=list(range(1, 6)),
359
+ # value=1,
360
+ # label="Sample 1"
361
+ # )
362
+ # sample2_dropdown = gr.Dropdown(
363
+ # choices=list(range(1, 6)),
364
+ # value=2,
365
+ # label="Sample 2"
366
+ # )
367
+
368
+ # with gr.Row():
369
+ # with gr.Column():
370
+ # gr.Markdown("### Sample 1")
371
+ # comp_input1 = gr.Video(label="Input")
372
+ # comp_optical1 = gr.Video(label="Optical Flow")
373
+ # comp_yolo1 = gr.Video(label="YOLO")
374
+ # comp_vggt1 = gr.Video(label="VGGT")
375
+ # comp_pcd1 = gr.Plot(label="Point Cloud")
376
+
377
+ # with gr.Column():
378
+ # gr.Markdown("### Sample 2")
379
+ # comp_input2 = gr.Video(label="Input")
380
+ # comp_optical2 = gr.Video(label="Optical Flow")
381
+ # comp_yolo2 = gr.Video(label="YOLO")
382
+ # comp_vggt2 = gr.Video(label="VGGT")
383
+ # comp_pcd2 = gr.Plot(label="Point Cloud")
384
+
385
+ # # Update comparison when dropdowns change
386
+ # def update_comparison(sample1_id, sample2_id):
387
+ # try:
388
+ # sample1_results = create_sample_gallery(sample1_id)
389
+ # sample2_results = create_sample_gallery(sample2_id)
390
+ # return sample1_results + sample2_results
391
+ # except Exception as e:
392
+ # print(f"Error updating comparison: {e}")
393
+ # return [None] * 10
394
+
395
+ # for dropdown in [sample1_dropdown, sample2_dropdown]:
396
+ # dropdown.change(
397
+ # update_comparison,
398
+ # inputs=[sample1_dropdown, sample2_dropdown],
399
+ # outputs=[
400
+ # comp_input1, comp_optical1, comp_yolo1, comp_vggt1, comp_pcd1,
401
+ # comp_input2, comp_optical2, comp_yolo2, comp_vggt2, comp_pcd2
402
+ # ]
403
+ # )
404
+
405
+
406
+ if __name__ == "__main__":
407
+ # Print file status for debugging
408
+ print("=== File Status Check ===")
409
+ for i in range(2, 9):
410
+ print(f"\nSample {i}:")
411
+ for key, path in SAMPLES[i].items():
412
+ status = "✅ Found" if path else "❌ Missing"
413
+ print(f" {key}: {status}")
414
+
415
+ print(f"\n=== Starting Gradio App ===")
416
+ demo.launch(
417
+ share=True,
418
+ server_name="127.0.0.1",
419
+ server_port=7861,
420
+ show_error=True,
421
+ inbrowser=True
422
+ )
app2.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import subprocess
4
+ import signal
5
+ import atexit
6
+ import platform
7
+
8
+ # Global variable to hold the process for the viewer
9
+ viser_process = None
10
+
11
+ def kill_process(proc):
12
+ if proc is None:
13
+ return
14
+ if platform.system() == "Windows":
15
+ proc.kill()
16
+ else:
17
+ os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
18
+
19
+
20
+ # Clean up function to kill the viser process when the app exits
21
+ def cleanup():
22
+ print("Cleaning up and stopping viser server...")
23
+ global viser_process
24
+ if viser_process:
25
+ kill_process(viser_process)
26
+ viser_process = None
27
+
28
+ atexit.register(cleanup)
29
+
30
+
31
+ def get_experiment_ids():
32
+ print("Getting experiment ids")
33
+ video_files = os.listdir("video")
34
+ print(f"Found {len(video_files)} video files")
35
+ return sorted([os.path.splitext(f)[0] for f in video_files if f.endswith(".mp4")])
36
+
37
+ # Get absolute paths for all files
38
+ def get_absolute_path(relative_path):
39
+ """Convert relative path to absolute path"""
40
+ return os.path.abspath(relative_path)
41
+
42
+ def check_file_exists(file_path):
43
+ """Check if file exists and return absolute path or None"""
44
+ abs_path = get_absolute_path(file_path)
45
+ if os.path.exists(abs_path):
46
+ return abs_path
47
+ else:
48
+ print(f"Warning: File not found: {file_path}")
49
+ return None
50
+ def get_file_paths(exp_id):
51
+ paths = {
52
+ "video": get_absolute_path(os.path.join("video", f"{exp_id}.mp4")),
53
+ "yolo": get_absolute_path(os.path.join("yolo", f"yolo{exp_id}.mp4")),
54
+ "optical_flow": get_absolute_path(os.path.join("optical_flow", f"optical_flow{exp_id}.mp4")),
55
+ "pcd": get_absolute_path(os.path.join("pcd", f"vggt_{exp_id}.pcd")),
56
+ }
57
+ for key, path in paths.items():
58
+ abs_path = check_file_exists(path)
59
+ paths[key] = abs_path
60
+ return paths
61
+
62
+ def show_results(exp_id):
63
+ # global viser_process
64
+
65
+ # if viser_process:
66
+ # print("Stopping previous viser server...")
67
+ # kill_process(viser_process)
68
+ # viser_process = None
69
+ print(f"Showing results for {exp_id}")
70
+ paths = get_file_paths(exp_id)
71
+
72
+ pcd_path = paths.get("pcd")
73
+ if pcd_path and os.path.exists(pcd_path):
74
+ print(f"Starting viser server for {pcd_path}...")
75
+ # For cross-platform compatibility, use shell=True on Windows
76
+ use_shell = platform.system() == "Windows"
77
+ preexec_fn = os.setsid if platform.system() != "Windows" else None
78
+
79
+ viser_process = subprocess.Popen(
80
+ ["python", "vis.py", pcd_path],
81
+ stdout=subprocess.PIPE,
82
+ stderr=subprocess.PIPE,
83
+ shell=use_shell,
84
+ preexec_fn=preexec_fn
85
+ )
86
+ print(f"Viser server started with PID: {viser_process.pid}")
87
+
88
+ iframe_html = '<iframe src="http://127.0.0.1:8088" style="width: 100%; height: 500px; border: none;"></iframe>'
89
+
90
+ return (
91
+ paths.get("video"),
92
+ paths.get("yolo"),
93
+ paths.get("optical_flow"),
94
+ iframe_html
95
+ )
96
+
97
+ with gr.Blocks() as demo:
98
+ print("Creating blocks")
99
+ gr.Markdown("# Experiment Results Gallery")
100
+
101
+ experiment_ids = get_experiment_ids()
102
+ print(f"Experiment ids: {experiment_ids}")
103
+ if not experiment_ids:
104
+ gr.Markdown("## No experiments found. Please add videos to the 'video' directory.")
105
+ else:
106
+ with gr.Row():
107
+ exp_id_dropdown = gr.Dropdown(
108
+ choices=experiment_ids,
109
+ label="Select Experiment ID",
110
+ value=experiment_ids[0]
111
+ )
112
+
113
+ gr.Markdown("## Input")
114
+ input_video = gr.Video(label="Input Video")
115
+
116
+ gr.Markdown("## Outputs")
117
+ with gr.Tabs():
118
+ with gr.TabItem("YOLO"):
119
+ yolo_video = gr.Video(label="YOLO Output")
120
+ with gr.TabItem("Optical Flow"):
121
+ optical_flow_video = gr.Video(label="Optical Flow Output")
122
+ with gr.TabItem("Point Cloud"):
123
+ pcd_vis = gr.HTML(label="Point Cloud Visualization")
124
+
125
+ print("Creating dropdown")
126
+ exp_id_dropdown.change(
127
+ fn=show_results,
128
+ inputs=exp_id_dropdown,
129
+ outputs=[input_video, yolo_video, optical_flow_video, pcd_vis]
130
+ )
131
+ print("Creating load")
132
+ # Trigger initial load
133
+ demo.load(
134
+ fn=show_results,
135
+ inputs=exp_id_dropdown,
136
+ outputs=[input_video, yolo_video, optical_flow_video, pcd_vis]
137
+ )
138
+
139
+
140
+ if __name__ == "__main__":
141
+ print("Launching demo")
142
+ demo.launch(
143
+ server_name="127.0.0.1",
144
+ server_port=7862,
145
+ show_error=True,
146
+ inbrowser=True
147
+ )
demo.py ADDED
File without changes
optical_flow/Assault002_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3eb2e0269756ce91d830f2ddc0e6f5df794cfc5babfa224165eb7ef982e3b492
3
+ size 6690566
optical_flow/Assault003_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f71f2368936e27949bd1bdab2a93be1e9efbece26fb157c45b1844a92fac018c
3
+ size 8017071
optical_flow/Assault004_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:52d41602da33fc2d4cd7495d4c52af965dbd656d688c786d1eb8cd34b2a529af
3
+ size 7577219
optical_flow/Assault005_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:da8f0ef439afa55a3867f2139bd9a4d3cc7d38576821e78fa7e1430a7e4608b6
3
+ size 30933897
optical_flow/Assault006_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c6412be8f2c28e73133969695388d90dd3ba8e3d4b43c62eca58cebcf0392d3c
3
+ size 16892093
optical_flow/Assault007_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:98abb50a5fe4777c2ca7d73b53743ef0a1a9fb864a8ad68d000621da6394e2e2
3
+ size 4405230
optical_flow/Assault008_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:23837a3ca35281c42d22703618208ecfbd9b8e6e713b963c3a67333415b7eab0
3
+ size 12775042
optical_flow/optical_flow1.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e0cac164b3a6c1f3c49113472f52a81edbee95a80898af5be8d0b6b9d4e2a5d9
3
+ size 21691817
optical_flow/optical_flow2.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3b69ee465f25400f2a5ecccb5e8bfed68fe6bd2a1686e2304f68da6e5f72624b
3
+ size 43082630
optical_flow/optical_flow3.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:48c26b3033ffe95f652c8ded8d184b4a2a318e341a4dd178ba39dd209428cc08
3
+ size 17186025
optical_flow/optical_flow4.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5f311fc286f68468695b76a18753b91d750a19f95948f7a6202ab27cfa60ba5e
3
+ size 35654798
optical_flow/optical_flow5.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f4ddbae0b718e69c3a0df57a7d97dc395216094aa729a93aef51bd8342dd4a4c
3
+ size 31908434
qa/Assault001_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault001_x264.mp4",
3
+ "video_name": "Assault001_x264",
4
+ "timestamp": "2025-06-23T21:17:48.641291",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频中发生了一起殴打事件。一名男子在与另一名男子发生争执后遭到殴打,导致他倒地不起。旁观者试图介入并帮助他,但殴打者继续攻击他。最终,殴打者离开现场,而旁观者则报警。整个过程被监控摄像头记录下来。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,殴打事件本身是一种异常行为,违反了社会秩序和法律。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "有四名男子参与了可疑活动,包括殴打者和旁观者。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "嫌疑人穿着深色上衣和浅色裤子,但其他外貌特征没有详细描述。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "嫌疑人是否携带任何物品或武器没有在视频中明确描述。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先与另一名男子发生争执,然后使用身体攻击手段殴打对方。旁观者试图介入并帮助他,但嫌疑人继续攻击。最终,嫌疑人离开现场。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人首先在晚上出现,然后在第二天的某个时间点再次出现。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是集体行动,因为旁观者试图介入并帮助被殴打的男子。"
54
+ }
55
+ ]
56
+ }
qa/Assault002_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault002_x264.mp4",
3
+ "video_name": "Assault002_x264",
4
+ "timestamp": "2025-06-23T21:18:13.126670",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频中显示的是一个办公室的内部,有多个桌子和椅子。在某个时刻,一名男子突然闯入办公室,并开始攻击其他工作人员。他使用暴力手段,对这些工作人员进行殴打和推搡。其他工作人员则试图保护自己并尝试离开现场。整个过程中,该男子的行为非常恶劣,给办公室内的工作人员造成了很大的伤害和恐惧。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,视频中存在异常行为。一名男子闯入办公室并使用暴力手段攻击其他工作人员,这是非常不寻常和非法的行为。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "视频中没有提供具体的参与人数,但可以确定至少有一名男子闯入办公室并使用暴力手段攻击其他工作人员。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "嫌疑人是一名男子,他闯入办公室并使用暴力手段攻击其他工作人员。他的外貌特征无法确定,但他的行为非常恶劣和非法。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "视频中没有提供关于嫌疑人是否携带任何物品或武器的信息。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先闯入办公室,然后开始攻击其他工作人员。他使用暴力手段进行殴打和推搡,对工作人员造成了很大的伤害和恐惧。整个过程中,他的行为非常恶劣和非法。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人出现在2017-03-25 12:54:12,闯入办公室并开始攻击其他工作人员。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是个人行为,嫌疑人闯入办公室并使用暴力手段攻击其他工作人员,而不是集体行动。"
54
+ }
55
+ ]
56
+ }
qa/Assault003_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault003_x264.mp4",
3
+ "video_name": "Assault003_x264",
4
+ "timestamp": "2025-06-23T21:18:38.255239",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频中显示了一组人聚集在某个地点,其中一些人开始发生身体冲突。冲突升级后,更多的人加入进来,导致场面变得混乱。最终,冲突结束,所有参与者都离开现场。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,视频中存在非法行为,包括身体冲突和殴打他人。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "视频中有多达七名参与者参与了可疑活动。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "嫌疑人穿着深色服装,但其他外貌特征无法确定。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "嫌疑人是否携带任何物品或武器无法确定。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先聚集在某个地点,然后发生身体冲突。冲突升级后,更多的人加入进来。最终,冲突结束,所有参与者都离开现场。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人首先在某个地点出现,然后参与身体冲突。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是集体行动,因为有多达七名参与者参与了非法活动。"
54
+ }
55
+ ]
56
+ }
qa/Assault004_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault004_x264.mp4",
3
+ "video_name": "Assault004_x264",
4
+ "timestamp": "2025-06-23T21:19:16.021012",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频中显示了四名男子在一条城市街道上进行非法活动。他们使用棍棒和刀具攻击一名受害者,导致受害者受伤并流血。这些行为发生在一个光线较暗的地区,可能是在深夜。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,视频中四名男子使用棍棒和刀具攻击受害者的行为是非法和异常的。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "四名男子参与了可疑活动。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "嫌疑人穿着白衣服和头套,使用棍棒攻击受害者。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "是的,嫌疑人携带棍棒和刀具进行攻击。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先使用棍棒攻击受害者,然后使用刀具进一步伤害受害者。最后,他们逃离现场。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人是在深夜时分出现的。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是集体行动,因为四名男子共同参与了攻击行为。"
54
+ }
55
+ ]
56
+ }
qa/Assault005_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault005_x264.mp4",
3
+ "video_name": "Assault005_x264",
4
+ "timestamp": "2025-06-23T21:19:44.105593",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频中显示了几个犯罪分子在深夜时分,潜入一个居民区的后院。他们使用工具和暴力手段,破坏了后院中的花坛和灌木。犯罪分子还使用了照明设备来帮助他们进行破坏活动。整个过程被监控摄像头记录了下来,为警方提供了有力的证据。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,视频中存在异常行为。几个犯罪分子在深夜时分潜入居民区的后院,并使用工具和暴力手段破坏花坛和灌木,这是非法和犯罪行为。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "有几个犯罪分子参与了可疑活动,但具体人数无法确定。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "嫌疑人穿着浅色的服装,但其他外貌特征无法确定。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "嫌疑人是否携带任何物品或武器无法确定,但他们在现场使用了工具和暴力手段。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先潜入后院,然后使用工具和暴力手段破坏花坛和灌木。整个过程被监控摄像头记录了下来。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人出现在深夜时分。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是集体行动,有几个犯罪分子参与了破坏活动。"
54
+ }
55
+ ]
56
+ }
qa/Assault006_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault006_x264.mp4",
3
+ "video_name": "Assault006_x264",
4
+ "timestamp": "2025-06-23T21:20:00.525212",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频中显示一个室内空间,可能是一个办公室或小型店铺。在视频的开始,一个穿着白上衣和黑背心的人进入这个空间。他随后开始攻击一个已经存在的个人,这导致了进一步的暴力行为。更多的人加入进来,形成一个混乱的场面,其中一些人试图控制局面,而其他人则参与殴打。整个过程中,暴力行为持续发生,直到最后,所有参与者都离开现场。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,视频中存在异常行为。暴力攻击和殴打是一种非法和不道德的行为,违反了社会规范和法律。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "参与可疑活动的人数无法确定,因为视频中没有提供具体的数字。但是,从视频的描述来看,至少有四到五个人参与了殴打和暴力行为。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "嫌疑人穿着白上衣和黑背心。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "嫌疑人是否携带任何物品或武器无法确定,因为视频中没有提供具体的细节。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先进入室内空间,然后开始攻击已经存在的个人。这导致了进一步的暴力行为,更多的人加入进来,形成一个混乱的场面。整个过程中,暴力行为持续发生,直到最后,所有参与者都离开现场。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人出现在视频的开始,即进入室内空间时。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是集体行动,因为更多的人加入进来,形成一个混乱的场面。"
54
+ }
55
+ ]
56
+ }
qa/Assault007_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault007_x264.mp4",
3
+ "video_name": "Assault007_x264",
4
+ "timestamp": "2025-06-23T21:21:17.317527",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频显示了一起正在进行的银行抢劫事件。一个人躺在地板上,似乎失去知觉或被制服,同时两个戴着面具并穿着深色衣服的人接近并与其互动。其中一个劫匪似乎拿着武器,可能是棒球棒或棍子,并被看到多次击打地上的那个人。然后劫匪们移动到自动取款机前,可能试图获取现金。这个场景表明在银行内正在发生暴力犯罪行为。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,视频中存在异常行为。两个穿着黄色和绿色面罩的武装人员闯入银行,对一个似乎失去知觉的人进行殴打,并试图从ATM机处获取资金,这表明了非法和暴力行为。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "有三个人参与了可疑活动。除了两个穿着黄色和绿色面罩的武装人员,还有一名穿着白大褂的人在视频中出现。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "两个嫌疑人穿着黄色和绿色面罩,而第三名嫌疑人则穿着白大褂。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "是的,两个嫌疑人携带武器,其中一人可能持有一根棒状物。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先闯入银行,对一个似乎失去知觉的人进行殴打。然后,他们接近ATM机,尝试获取资金。最后,他们离开银行现场。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人首先在2016-06-09 04:32:51出现。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是集体行动,因为有三个人参与了非法活动。"
54
+ }
55
+ ]
56
+ }
qa/Assault008_x264.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "video_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/videos2/Assault008_x264.mp4",
3
+ "video_name": "Assault008_x264",
4
+ "timestamp": "2025-06-23T21:21:39.536778",
5
+ "model_path": "/public/share/yinxiangrong/qinxiaoyu/kdc2024/S/video_chat/VideoChat-Flash-Qwen2-7B_res448",
6
+ "max_num_frames": 512,
7
+ "generation_config": {
8
+ "do_sample": false,
9
+ "temperature": 0.0,
10
+ "max_new_tokens": 1024,
11
+ "top_p": 0.1,
12
+ "num_beams": 1
13
+ },
14
+ "qa_pairs": [
15
+ {
16
+ "question_id": 1,
17
+ "question": "请描述视频中的场景和事件",
18
+ "answer": "视频中显示了一群人围攻并殴打一个男性,导致他受伤倒地。旁观者则在旁边观看。事件发生后,旁观者逐渐散去,而施暴者则继续对受害者进行攻击。最后,施暴者也离开现场,留下受害者一人倒地。"
19
+ },
20
+ {
21
+ "question_id": 2,
22
+ "question": "视频中是否存在异常行为?",
23
+ "answer": "是的,视频中存在非法行为,即一群人围攻并殴打一个男性,导致他受伤倒地。"
24
+ },
25
+ {
26
+ "question_id": 3,
27
+ "question": "有多少人参与了可疑活动?",
28
+ "answer": "视频中有多达10名男性参与了围攻并殴打受害者的非法活动。"
29
+ },
30
+ {
31
+ "question_id": 4,
32
+ "question": "嫌疑人外貌是什么样子?",
33
+ "answer": "嫌疑人穿着深色衣服,但其他外貌特征没有详细描述。"
34
+ },
35
+ {
36
+ "question_id": 5,
37
+ "question": "嫌疑人是否携带任何物品或武器?",
38
+ "answer": "没有详细描述嫌疑人是否携带任何物品或武器。"
39
+ },
40
+ {
41
+ "question_id": 6,
42
+ "question": "请描述嫌疑人行为的步骤",
43
+ "answer": "嫌疑人首先围攻并殴打受害者,导致他受伤倒地。然后旁观者逐渐散去,而施暴者则继续对受害者进行攻击。最后,施暴者也离开现场,留下受害者一人倒地。"
44
+ },
45
+ {
46
+ "question_id": 7,
47
+ "question": "嫌疑人出现在什么时候?",
48
+ "answer": "嫌疑人首先在2013-05-19 06:26:03左右出现。"
49
+ },
50
+ {
51
+ "question_id": 9,
52
+ "question": "这是集体行动还是个人行为?",
53
+ "answer": "这是集体行动,因为有多达10名男性参与了围攻并殴打受害者的非法活动。"
54
+ }
55
+ ]
56
+ }
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ numpy<2.0
3
+ plotly
vggt/Assault002_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:30f8db800bfa502439108e2caa877d611d845d78713f1da72958dd3552d58a5f
3
+ size 3899165
vggt/Assault003_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4cf84fca6a9c2d1b58ef756192663033e5d8de036f41735f734c20e4052a1446
3
+ size 8000515
vggt/Assault004_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:76d8427a129b29cec9c55c388d76efb251adbc4fac885c992f4932fd9b074f10
3
+ size 3888965
vggt/Assault005_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e174cc4b3a0d16a078ff243205367542febda1bc61f90534d0a3adb2430f13e3
3
+ size 7023409
vggt/Assault006_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:08f92bbdb746420faa82022130aace4e12b239d49fd5e6117a891db898e2fe40
3
+ size 6910917
vggt/Assault007_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:180698e3db8eb51d7a51439876fc5629b88cc1ab8534b2b9734fc180044698d8
3
+ size 9645884
vggt/Assault008_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d2fef1b2a40233e8d68589221378d563eb169a125412227df815b4990f6e452
3
+ size 5426888
video/Assault001_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0bc93b52a6975b6b95dde2bd068f289342929958bef5e0951bfb886394b449c6
3
+ size 9759376
video/Assault002_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:63cf01b45e9f825342c76dceba336943019062e307b5fdbc7a283f9e36d22b69
3
+ size 12435565
video/Assault003_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:791f46b7de817e09efe5b63c992c3faa848b5bc3469950c37438fb17473632bf
3
+ size 17984773
video/Assault004_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d38600ef7f1efcc22f8638eb12e1cd55292713d9429bb0051e675bb9f34e09aa
3
+ size 17181608
video/Assault005_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:41b0db187a44aaa911568a746c75b5dd71be229bad118774a95289470e187435
3
+ size 4839833
video/Assault006_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0e7028c9a398ee742dae444239dcd33be89aa61610fd7426fc2271e554c9fb99
3
+ size 32982673
video/Assault007_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:45f245a3c05042e8704d9377ec8a4626e5942f9dfaafd2623d64a1d5457bbe05
3
+ size 8220098
video/Assault008_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3e53629b0b21039a270dc6b1f3a29500c724fb36be905dc42a3528bd5f39f8cf
3
+ size 30576980
vis.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import viser
2
+ import open3d as o3d
3
+ import numpy as np
4
+ import sys
5
+ import time
6
+
7
+ if len(sys.argv) < 2:
8
+ print("Usage: python vis.py <path_to_pcd_file>")
9
+ sys.exit(1)
10
+
11
+ pcd_file = sys.argv[1]
12
+ pcd = o3d.io.read_point_cloud(pcd_file)
13
+ points = np.asarray(pcd.points)
14
+ colors = np.asarray(pcd.colors).astype(float) if pcd.has_colors() else None
15
+
16
+ # 启动 Viser 服务器
17
+ server = viser.ViserServer(port=8088) # 可自定义端口
18
+ server.scene.background_color = (0.1, 0.1, 0.1)
19
+ # 添加点云
20
+ server.add_point_cloud(
21
+ name="/pointcloud",
22
+ points=points,
23
+ colors=colors,
24
+ point_size=0.003,
25
+ )
26
+
27
+ # Keep the script running
28
+ while True:
29
+ time.sleep(0.1)
yolo/Assault002_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4fe5b00266d09f6370dc730709c525642059c857685f6b0099e27ee278c8b49c
3
+ size 8419118
yolo/Assault003_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:40247a6997fa429b13ab5fad8480f02679e88f524dfaa127eae781032cd812fe
3
+ size 9052657
yolo/Assault004_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:33b92d3d6702e3a460644e84dd651b518246be6024d55a857912a82b184d44ec
3
+ size 10190470
yolo/Assault005_x264.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:53ec07018577b2b66d5f635d448bcd9ba4670060d0d239e9564a7f32b8d89fd3
3
+ size 31140308