Update app.py
Browse files
app.py
CHANGED
|
@@ -250,14 +250,30 @@ def process_video(video_file, num_frames, segment_duration, num_segments):
|
|
| 250 |
return [], f"Error processing video: {str(e)}", []
|
| 251 |
|
| 252 |
# Create Gradio interface
|
| 253 |
-
with gr.Blocks(title="
|
| 254 |
gr.Markdown("""
|
| 255 |
-
#
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
|
| 260 |
-
|
|
|
|
|
|
|
| 261 |
""")
|
| 262 |
|
| 263 |
with gr.Row():
|
|
@@ -308,38 +324,12 @@ with gr.Blocks(title="Video Frame Sampling Tool") as demo:
|
|
| 308 |
)
|
| 309 |
indices_output = gr.JSON(label="Frame Indices", visible=False)
|
| 310 |
|
| 311 |
-
# Examples
|
| 312 |
-
gr.Examples(
|
| 313 |
-
examples=[
|
| 314 |
-
[8, 4, 2.0],
|
| 315 |
-
[16, 8, 1.5],
|
| 316 |
-
[4, 2, 3.0],
|
| 317 |
-
[24, 6, 2.5],
|
| 318 |
-
],
|
| 319 |
-
inputs=[num_frames, num_segments, segment_duration],
|
| 320 |
-
label="Example Configurations"
|
| 321 |
-
)
|
| 322 |
-
|
| 323 |
# Connect the processing function
|
| 324 |
process_btn.click(
|
| 325 |
fn=process_video,
|
| 326 |
inputs=[video_input, num_frames, segment_duration, num_segments],
|
| 327 |
outputs=[gallery_output, info_output, indices_output]
|
| 328 |
)
|
| 329 |
-
|
| 330 |
-
gr.Markdown("""
|
| 331 |
-
### How it works:
|
| 332 |
-
1. The video is divided into the specified number of segments
|
| 333 |
-
2. Each segment has a maximum duration as specified
|
| 334 |
-
3. Frames are sampled evenly from within each segment
|
| 335 |
-
4. The algorithm ensures exactly the requested number of frames are returned
|
| 336 |
-
5. If the video is too short, it falls back to uniform sampling
|
| 337 |
-
|
| 338 |
-
### Tips:
|
| 339 |
-
- Use more segments for longer videos to get better temporal coverage
|
| 340 |
-
- Adjust segment duration based on the pace of content in your video
|
| 341 |
-
- For short videos, use fewer segments with shorter durations
|
| 342 |
-
""")
|
| 343 |
|
| 344 |
# Launch the app
|
| 345 |
if __name__ == "__main__":
|
|
|
|
| 250 |
return [], f"Error processing video: {str(e)}", []
|
| 251 |
|
| 252 |
# Create Gradio interface
|
| 253 |
+
with gr.Blocks(title="PATS: Proficiency-Aware Temporal Sampling for Multi-View Sports Skill Assessment") as demo:
|
| 254 |
gr.Markdown("""
|
| 255 |
+
# PATS: Proficiency-Aware Temporal Sampling for Multi-View Sports Skill Assessment
|
| 256 |
+
|
| 257 |
+
PATS (Proficiency-Aware Temporal Sampling) is a novel video sampling strategy designed specifically for automated sports skill assessment.
|
| 258 |
+
Unlike traditional methods that randomly sample frames or use uniform intervals, PATS preserves complete fundamental movements within continuous temporal segments.
|
| 259 |
+
The paper presenting PATS has been accepted at the 2025 4th IEEE Sport Technology and Research Workshop.
|
| 260 |
+
|
| 261 |
+
This tool showcases the PATS sampling strategy. Find out more at the project page: https://edowhite.github.io/PATS
|
| 262 |
+
|
| 263 |
+
## Core Concept
|
| 264 |
+
The key insight is that athletic proficiency manifests through structured temporal patterns that require observing complete, uninterrupted movements.
|
| 265 |
+
PATS addresses this by:
|
| 266 |
+
|
| 267 |
+
- **Extracting continuous temporal segments** rather than isolated frames
|
| 268 |
+
- **Preserving natural movement flow** essential for distinguishing expert from novice performance
|
| 269 |
+
- **Distributing multiple segments** across the video timeline to maximize information coverage
|
| 270 |
+
|
| 271 |
+
## Performance
|
| 272 |
+
When applied to SkillFormer on the EgoExo4D benchmark, PATS achieves:
|
| 273 |
|
| 274 |
+
- **Consistent improvements** across all viewing configurations (+0.65% to +3.05%)
|
| 275 |
+
- **Substantial domain-specific gains:** +26.22% in bouldering, +2.39% in music, +1.13% in basketball
|
| 276 |
+
|
| 277 |
""")
|
| 278 |
|
| 279 |
with gr.Row():
|
|
|
|
| 324 |
)
|
| 325 |
indices_output = gr.JSON(label="Frame Indices", visible=False)
|
| 326 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 327 |
# Connect the processing function
|
| 328 |
process_btn.click(
|
| 329 |
fn=process_video,
|
| 330 |
inputs=[video_input, num_frames, segment_duration, num_segments],
|
| 331 |
outputs=[gallery_output, info_output, indices_output]
|
| 332 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
|
| 334 |
# Launch the app
|
| 335 |
if __name__ == "__main__":
|