A Gradio 5 component for video movement analysis using Laban Movement Analysis (LMA) with MCP support for AI agents
Project description
title: Laban Movement Analysis - Complete Suite emoji: 🎭 colorFrom: blue colorTo: green sdk: gradio sdk_version: 5.0.0 app_file: app.py pinned: false license: mit tags:
- laban-movement-analysis
- pose-estimation
- movement-analysis
- video-analysis
- webrtc
- youtube
- vimeo
- mcp
- agent-ready
- computer-vision
- mediapipe
- yolo
- gradio short_description: Professional movement analysis with pose estimation, AI action recognition, real-time WebRTC, YouTube/Vimeo support, and agent automation by Csaba Bolyós
gradio_labanmovementanalysis
A Gradio 5 component for video movement analysis using Laban Movement Analysis (LMA) with MCP support for AI agents
Installation
pip install gradio_labanmovementanalysis
Usage
"""
Unified Laban Movement Analysis Demo
Comprehensive interface combining all features:
- Standard LMA analysis
- Enhanced features (WebRTC, YouTube/Vimeo)
- Agent API (batch processing, filtering)
- Real-time analysis
- Model comparison
Created by: Csaba Bolyós (BladeSzaSza)
Contact: bladeszasza@gmail.com
GitHub: https://github.com/bladeszasza
LinkedIn: https://www.linkedin.com/in/csaba-bolyós-00a11767/
Hugging Face: https://huggingface.co/BladeSzaSza
Heavy Beta Version - Under Active Development
"""
import gradio as gr
import sys
from pathlib import Path
from typing import Dict, Any, List, Tuple
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent / "backend"))
from gradio_labanmovementanalysis import LabanMovementAnalysis
# Import agent API if available
try:
from gradio_labanmovementanalysis.agent_api import (
LabanAgentAPI,
PoseModel,
MovementDirection,
MovementIntensity
)
HAS_AGENT_API = True
except ImportError:
HAS_AGENT_API = False
# Import WebRTC components if available
try:
from gradio_webrtc import WebRTC
from gradio_labanmovementanalysis.webrtc_handler import (
webrtc_detection,
get_rtc_configuration
)
HAS_WEBRTC = True
except ImportError as e:
print(f"WebRTC import failed: {e}")
HAS_WEBRTC = False
# Initialize components
try:
# Initialize with WebRTC support
analyzer = LabanMovementAnalysis(
enable_webrtc=True,
enable_visualization=True
)
print("✅ Core features initialized successfully")
except Exception as e:
print(f"Warning: Some features may not be available: {e}")
analyzer = LabanMovementAnalysis(enable_webrtc=False)
# Initialize agent API if available
agent_api = None
if HAS_AGENT_API:
try:
agent_api = LabanAgentAPI()
except Exception as e:
print(f"Warning: Agent API not available: {e}")
agent_api = None
def process_video_standard(video, model, enable_viz, include_keypoints):
"""Standard video processing function."""
if video is None:
return None, None
try:
json_output, video_output = analyzer.process_video(
video,
model=model,
enable_visualization=enable_viz,
include_keypoints=include_keypoints
)
return json_output, video_output
except Exception as e:
return {"error": str(e)}, None
def process_video_enhanced(video_input, model, enable_viz, include_keypoints):
"""Enhanced video processing with all new features."""
if not video_input:
return {"error": "No video provided"}, None
try:
# Handle both file upload and URL input
video_path = video_input.name if hasattr(video_input, 'name') else video_input
json_result, viz_result = analyzer.process_video(
video_path,
model=model,
enable_visualization=enable_viz,
include_keypoints=include_keypoints
)
return json_result, viz_result
except Exception as e:
error_result = {"error": str(e)}
return error_result, None
def process_video_for_agent(video, model, output_format="summary"):
"""Process video with agent-friendly output format."""
if not HAS_AGENT_API or agent_api is None:
return {"error": "Agent API not available"}
if not video:
return {"error": "No video provided"}
try:
model_enum = PoseModel(model)
result = agent_api.analyze(video, model=model_enum, generate_visualization=False)
if output_format == "summary":
return {"summary": agent_api.get_movement_summary(result)}
elif output_format == "structured":
return {
"success": result.success,
"direction": result.dominant_direction.value,
"intensity": result.dominant_intensity.value,
"speed": result.dominant_speed,
"fluidity": result.fluidity_score,
"expansion": result.expansion_score,
"segments": len(result.movement_segments)
}
else: # json
return result.raw_data
except Exception as e:
return {"error": str(e)}
def batch_process_videos(files, model):
"""Process multiple videos in batch."""
if not HAS_AGENT_API or agent_api is None:
return {"error": "Agent API not available"}
if not files:
return {"error": "No videos provided"}
try:
video_paths = [f.name for f in files]
results = agent_api.batch_analyze(video_paths, model=PoseModel(model), parallel=True)
output = {
"total_videos": len(results),
"successful": sum(1 for r in results if r.success),
"failed": sum(1 for r in results if not r.success),
"results": []
}
for result in results:
output["results"].append({
"video": Path(result.video_path).name,
"success": result.success,
"summary": agent_api.get_movement_summary(result) if result.success else result.error
})
return output
except Exception as e:
return {"error": str(e)}
def filter_videos_by_movement(files, direction, intensity, min_fluidity, min_expansion):
"""Filter videos based on movement characteristics."""
if not HAS_AGENT_API or agent_api is None:
return {"error": "Agent API not available"}
if not files:
return {"error": "No videos provided"}
try:
video_paths = [f.name for f in files]
dir_filter = MovementDirection(direction) if direction != "any" else None
int_filter = MovementIntensity(intensity) if intensity != "any" else None
filtered = agent_api.filter_by_movement(
video_paths,
direction=dir_filter,
intensity=int_filter,
min_fluidity=min_fluidity if min_fluidity > 0 else None,
min_expansion=min_expansion if min_expansion > 0 else None
)
return {
"total_analyzed": len(video_paths),
"matching_videos": len(filtered),
"matches": [
{
"video": Path(r.video_path).name,
"direction": r.dominant_direction.value,
"intensity": r.dominant_intensity.value,
"fluidity": r.fluidity_score,
"expansion": r.expansion_score
}
for r in filtered
]
}
except Exception as e:
return {"error": str(e)}
def compare_models(video, model1, model2):
"""Compare two different pose models on the same video."""
if not video:
return "No video provided"
try:
# Analyze with both models
result1, _ = analyzer.process_video(video, model=model1, enable_visualization=False)
result2, _ = analyzer.process_video(video, model=model2, enable_visualization=False)
# Extract key metrics for comparison
def extract_metrics(result):
summary = result.get("movement_analysis", {}).get("summary", {})
return {
"direction": summary.get("direction", {}).get("dominant", "unknown"),
"intensity": summary.get("intensity", {}).get("dominant", "unknown"),
"speed": summary.get("speed", {}).get("dominant", "unknown"),
"frame_count": result.get("video_info", {}).get("frame_count", 0)
}
metrics1 = extract_metrics(result1)
metrics2 = extract_metrics(result2)
# Create comparison table data
comparison_data = [
["Direction", metrics1["direction"], metrics2["direction"],
"✓" if metrics1["direction"] == metrics2["direction"] else "✗"],
["Intensity", metrics1["intensity"], metrics2["intensity"],
"✓" if metrics1["intensity"] == metrics2["intensity"] else "✗"],
["Speed", metrics1["speed"], metrics2["speed"],
"✓" if metrics1["speed"] == metrics2["speed"] else "✗"],
["Frames Processed", str(metrics1["frame_count"]), str(metrics2["frame_count"]),
"✓" if metrics1["frame_count"] == metrics2["frame_count"] else "✗"]
]
return comparison_data
except Exception as e:
return [["Error", str(e), "", ""]]
def start_webrtc_stream(model):
"""Start WebRTC real-time analysis."""
try:
success = analyzer.start_webrtc_stream(model)
if success:
return "🟢 Stream Active", {"status": "streaming", "model": model}
else:
return "🔴 Failed to start", {"status": "error"}
except Exception as e:
return f"🔴 Error: {str(e)}", {"status": "error"}
def stop_webrtc_stream():
"""Stop WebRTC real-time analysis."""
try:
success = analyzer.stop_webrtc_stream()
if success:
return "🟡 Stream Stopped", {"status": "stopped"}
else:
return "🔴 Failed to stop", {"status": "error"}
except Exception as e:
return f"🔴 Error: {str(e)}", {"status": "error"}
def create_unified_demo():
"""Create the unified comprehensive demo."""
with gr.Blocks(
title="Laban Movement Analysis - Complete Suite by Csaba Bolyós",
theme=gr.themes.Soft(),
css="""
.main-header {
background: linear-gradient(135deg, #40826D 0%, #2E5E4A 50%, #1B3A2F 100%);
color: white;
padding: 30px;
border-radius: 10px;
margin-bottom: 20px;
text-align: center;
}
.feature-card {
border: 1px solid #e1e5e9;
border-radius: 8px;
padding: 16px;
margin: 8px 0;
background: #f8f9fa;
}
.json-output {
max-height: 600px;
overflow-y: auto;
font-family: monospace;
font-size: 12px;
}
.author-info {
background: linear-gradient(135deg, #40826D 0%, #2E5E4A 100%);
color: white;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
text-align: center;
}
"""
) as demo:
# Main Header
gr.HTML("""
<div class="main-header">
<h1>🎭 Laban Movement Analysis - Complete Suite</h1>
<p style="font-size: 18px; margin: 10px 0;">
Professional movement analysis with pose estimation, AI action recognition,
real-time processing, and agent automation
</p>
<p style="font-size: 14px; opacity: 0.9;">
Supports YouTube/Vimeo URLs • WebRTC Streaming • 20+ Pose Models • MCP Integration
</p>
<p style="font-size: 12px; margin-top: 15px; opacity: 0.8;">
<strong>Version 0.01-beta</strong> - Heavy Beta Under Active Development
</p>
</div>
""")
with gr.Tabs():
# Tab 1: Standard Analysis
with gr.Tab("🎬 Standard Analysis"):
gr.Markdown("""
### Classic Laban Movement Analysis
Upload a video file to analyze movement using traditional LMA metrics with pose estimation.
""")
with gr.Row():
with gr.Column(scale=1):
video_input_std = gr.Video(
label="Upload Video",
sources=["upload"],
format="mp4"
)
model_dropdown_std = gr.Dropdown(
choices=["mediapipe", "movenet", "yolo"],
value="mediapipe",
label="Pose Estimation Model"
)
with gr.Row():
enable_viz_std = gr.Checkbox(
value=True,
label="Generate Visualization"
)
include_keypoints_std = gr.Checkbox(
value=False,
label="Include Keypoints"
)
process_btn_std = gr.Button("Analyze Movement", variant="primary")
gr.Examples(
examples=[
["examples/balette.mov"],
["examples/balette.mp4"],
],
inputs=video_input_std,
label="Example Videos"
)
with gr.Column(scale=2):
with gr.Tab("Analysis Results"):
json_output_std = gr.JSON(
label="Movement Analysis (JSON)",
elem_classes=["json-output"]
)
with gr.Tab("Visualization"):
video_output_std = gr.Video(
label="Annotated Video",
format="mp4"
)
gr.Markdown("""
**Visualization Guide:**
- 🦴 **Skeleton**: Pose keypoints and connections
- 🌊 **Trails**: Motion history (fading lines)
- ➡️ **Arrows**: Movement direction indicators
- 🎨 **Colors**: Green (low) → Orange (medium) → Red (high) intensity
""")
process_btn_std.click(
fn=process_video_standard,
inputs=[video_input_std, model_dropdown_std, enable_viz_std, include_keypoints_std],
outputs=[json_output_std, video_output_std],
api_name="analyze_standard"
)
# Tab 2: Enhanced Analysis
with gr.Tab("🚀 Enhanced Analysis"):
gr.Markdown("""
### Advanced Analysis with AI and URL Support
Analyze videos from URLs (YouTube/Vimeo), use advanced pose models, and get AI-powered insights.
""")
with gr.Row():
with gr.Column(scale=1):
gr.HTML('<div class="feature-card">')
gr.Markdown("**Video Input**")
# Changed from textbox to file upload as requested
video_input_enh = gr.File(
label="Upload Video or Drop File",
file_types=["video"],
type="filepath"
)
# URL input option
url_input_enh = gr.Textbox(
label="Or Enter Video URL",
placeholder="YouTube URL, Vimeo URL, or direct video URL",
info="Leave file upload empty to use URL"
)
gr.Examples(
examples=[
["examples/balette.mov"],
["https://www.youtube.com/shorts/RX9kH2l3L8U"],
["https://vimeo.com/815392738"]
],
inputs=url_input_enh,
label="Example URLs"
)
gr.Markdown("**Model Selection**")
model_select_enh = gr.Dropdown(
choices=[
# MediaPipe variants
"mediapipe-lite", "mediapipe-full", "mediapipe-heavy",
# MoveNet variants
"movenet-lightning", "movenet-thunder",
# YOLO variants (added X models)
"yolo-v8-n", "yolo-v8-s", "yolo-v8-m", "yolo-v8-l", "yolo-v8-x",
# YOLO v11 variants
"yolo-v11-n", "yolo-v11-s", "yolo-v11-m", "yolo-v11-l", "yolo-v11-x"
],
value="mediapipe-full",
label="Advanced Pose Models",
info="17+ model variants available"
)
gr.Markdown("**Analysis Options**")
with gr.Row():
enable_viz_enh = gr.Checkbox(value=True, label="Visualization")
with gr.Row():
include_keypoints_enh = gr.Checkbox(value=False, label="Raw Keypoints")
analyze_btn_enh = gr.Button("🚀 Enhanced Analysis", variant="primary", size="lg")
gr.HTML('</div>')
with gr.Column(scale=2):
with gr.Tab("📊 Analysis"):
analysis_output_enh = gr.JSON(label="Enhanced Analysis Results")
with gr.Tab("🎥 Visualization"):
viz_output_enh = gr.Video(label="Annotated Video")
def process_enhanced_input(file_input, url_input, model, enable_viz, include_keypoints):
"""Process either file upload or URL input."""
video_source = file_input if file_input else url_input
return process_video_enhanced(video_source, model, enable_viz, include_keypoints)
analyze_btn_enh.click(
fn=process_enhanced_input,
inputs=[video_input_enh, url_input_enh, model_select_enh, enable_viz_enh, include_keypoints_enh],
outputs=[analysis_output_enh, viz_output_enh],
api_name="analyze_enhanced"
)
# Tab 3: Agent API
with gr.Tab("🤖 Agent API"):
gr.Markdown("""
### AI Agent & Automation Features
Batch processing, filtering, and structured outputs designed for AI agents and automation.
""")
with gr.Tabs():
with gr.Tab("Single Analysis"):
with gr.Row():
with gr.Column():
video_input_agent = gr.Video(label="Upload Video", sources=["upload"])
model_select_agent = gr.Dropdown(
choices=["mediapipe", "movenet", "yolo"],
value="mediapipe",
label="Model"
)
output_format_agent = gr.Radio(
choices=["summary", "structured", "json"],
value="summary",
label="Output Format"
)
analyze_btn_agent = gr.Button("Analyze", variant="primary")
with gr.Column():
output_display_agent = gr.JSON(label="Agent Output")
analyze_btn_agent.click(
fn=process_video_for_agent,
inputs=[video_input_agent, model_select_agent, output_format_agent],
outputs=output_display_agent,
api_name="analyze_agent"
)
with gr.Tab("Batch Processing"):
with gr.Row():
with gr.Column():
batch_files = gr.File(
label="Upload Multiple Videos",
file_count="multiple",
file_types=["video"]
)
batch_model = gr.Dropdown(
choices=["mediapipe", "movenet", "yolo"],
value="mediapipe",
label="Model"
)
batch_btn = gr.Button("Process Batch", variant="primary")
with gr.Column():
batch_output = gr.JSON(label="Batch Results")
batch_btn.click(
fn=batch_process_videos,
inputs=[batch_files, batch_model],
outputs=batch_output,
api_name="batch_analyze"
)
with gr.Tab("Movement Filter"):
with gr.Row():
with gr.Column():
filter_files = gr.File(
label="Videos to Filter",
file_count="multiple",
file_types=["video"]
)
with gr.Group():
direction_filter = gr.Dropdown(
choices=["any", "up", "down", "left", "right", "stationary"],
value="any",
label="Direction Filter"
)
intensity_filter = gr.Dropdown(
choices=["any", "low", "medium", "high"],
value="any",
label="Intensity Filter"
)
fluidity_threshold = gr.Slider(0.0, 1.0, 0.0, label="Min Fluidity")
expansion_threshold = gr.Slider(0.0, 1.0, 0.0, label="Min Expansion")
filter_btn = gr.Button("Apply Filters", variant="primary")
with gr.Column():
filter_output = gr.JSON(label="Filtered Results")
filter_btn.click(
fn=filter_videos_by_movement,
inputs=[filter_files, direction_filter, intensity_filter,
fluidity_threshold, expansion_threshold],
outputs=filter_output,
api_name="filter_videos"
)
# Tab 4: Real-time WebRTC
with gr.Tab("📹 Real-time Analysis"):
gr.Markdown("""
### Live Camera Movement Analysis
Real-time pose detection and movement analysis from your webcam using WebRTC.
**Grant camera permissions when prompted for best experience.**
""")
# Official Gradio WebRTC approach (compatible with NumPy 1.x)
if HAS_WEBRTC:
# Get RTC configuration
rtc_config = get_rtc_configuration()
# Custom CSS following official guide
css_webrtc = """
.my-group {max-width: 480px !important; max-height: 480px !important;}
.my-column {display: flex !important; justify-content: center !important; align-items: center !important;}
"""
with gr.Column(elem_classes=["my-column"]):
with gr.Group(elem_classes=["my-group"]):
# Official WebRTC Component
webrtc_stream = WebRTC(
label="🎥 Live Camera Stream",
rtc_configuration=rtc_config
)
webrtc_model = gr.Dropdown(
choices=["mediapipe-lite", "movenet-lightning", "yolo-v11-n"],
value="mediapipe-lite",
label="Pose Model",
info="Optimized for real-time processing"
)
confidence_slider = gr.Slider(
label="Detection Confidence",
minimum=0.0,
maximum=1.0,
step=0.05,
value=0.5,
info="Higher = fewer false positives"
)
# Official WebRTC streaming setup following Gradio guide
webrtc_stream.stream(
fn=webrtc_detection,
inputs=[webrtc_stream, webrtc_model, confidence_slider],
outputs=[webrtc_stream],
time_limit=10 # Following official guide: 10 seconds per user
)
# Info display
gr.HTML("""
<div style="background: #e8f4fd; padding: 15px; border-radius: 8px; margin-top: 10px;">
<h4>📹 WebRTC Pose Analysis</h4>
<p style="margin: 5px 0;">Real-time movement analysis using your webcam</p>
<h4>🔒 Privacy</h4>
<p style="margin: 5px 0;">Processing happens locally - no video data stored</p>
<h4>💡 Usage</h4>
<ul style="margin: 5px 0; padding-left: 20px;">
<li>Grant camera permission when prompted</li>
<li>Move in front of camera to see pose detection</li>
<li>Adjust confidence threshold as needed</li>
</ul>
</div>
""")
else:
# Fallback if WebRTC component not available
gr.HTML("""
<div style="text-align: center; padding: 50px; border: 2px dashed #ff6b6b; border-radius: 8px; background: #ffe0e0;">
<h3>📦 WebRTC Component Required</h3>
<p><strong>To enable real-time camera analysis, install:</strong></p>
<code style="background: #f0f0f0; padding: 10px; border-radius: 4px; display: block; margin: 10px 0;">
pip install gradio-webrtc twilio
</code>
<p style="margin-top: 15px;"><em>Use Enhanced Analysis tab for video files meanwhile</em></p>
</div>
""")
# Tab 5: Model Comparison
with gr.Tab("⚖️ Model Comparison"):
gr.Markdown("""
### Compare Pose Estimation Models
Analyze the same video with different models to compare accuracy and results.
""")
with gr.Column():
comparison_video = gr.Video(
label="Video for Comparison",
sources=["upload"]
)
with gr.Row():
model1_comp = gr.Dropdown(
choices=["mediapipe-full", "movenet-thunder", "yolo-v11-s"],
value="mediapipe-full",
label="Model 1"
)
model2_comp = gr.Dropdown(
choices=["mediapipe-full", "movenet-thunder", "yolo-v11-s"],
value="yolo-v11-s",
label="Model 2"
)
compare_btn = gr.Button("🔄 Compare Models", variant="primary")
comparison_results = gr.DataFrame(
headers=["Metric", "Model 1", "Model 2", "Match"],
label="Comparison Results"
)
compare_btn.click(
fn=compare_models,
inputs=[comparison_video, model1_comp, model2_comp],
outputs=comparison_results,
api_name="compare_models"
)
# Tab 6: Documentation
with gr.Tab("📚 Documentation"):
gr.Markdown("""
# Complete Feature Documentation
## 🎥 Video Input Support
- **Local Files**: MP4, AVI, MOV, WebM formats
- **YouTube**: Automatic download from YouTube URLs
- **Vimeo**: Automatic download from Vimeo URLs
- **Direct URLs**: Any direct video file URL
## 🤖 Pose Estimation Models
### MediaPipe (Google) - 33 3D Landmarks
- **Lite**: Fastest CPU performance
- **Full**: Balanced accuracy/speed (recommended)
- **Heavy**: Highest accuracy
### MoveNet (Google) - 17 COCO Keypoints
- **Lightning**: Mobile-optimized, very fast
- **Thunder**: Higher accuracy variant
### YOLO (Ultralytics) - 17 COCO Keypoints
- **v8 variants**: n/s/m/l/x sizes (nano to extra-large)
- **v11 variants**: Latest with improved accuracy (n/s/m/l/x)
- **Multi-person**: Supports multiple people in frame
## 📹 Real-time WebRTC
- **Live Camera**: Direct webcam access via WebRTC
- **Low Latency**: Sub-100ms processing
- **Adaptive Quality**: Automatic performance optimization
- **Live Overlay**: Real-time pose and metrics display
## 🤖 Agent & MCP Integration
### API Endpoints
- `/analyze_standard` - Basic LMA analysis
- `/analyze_enhanced` - Advanced analysis with all features
- `/analyze_agent` - Agent-optimized output
- `/batch_analyze` - Multiple video processing
- `/filter_videos` - Movement-based filtering
- `/compare_models` - Model comparison
### MCP Server
```bash
# Start MCP server for AI assistants
python -m backend.mcp_server
```
### Python API
```python
from gradio_labanmovementanalysis import LabanMovementAnalysis
# Initialize with all features
analyzer = LabanMovementAnalysis(
enable_webrtc=True
)
# Analyze YouTube video
result, viz = analyzer.process_video(
"https://youtube.com/watch?v=...",
model="yolo-v11-s"
)
```
## 📊 Output Formats
### Summary Format
Human-readable movement analysis summary.
### Structured Format
```json
{
"success": true,
"direction": "up",
"intensity": "medium",
"fluidity": 0.85,
"expansion": 0.72
}
```
### Full JSON Format
Complete frame-by-frame analysis with all metrics.
## 🎯 Applications
- **Sports**: Technique analysis and performance tracking
- **Dance**: Choreography analysis and movement quality
- **Healthcare**: Physical therapy and rehabilitation
- **Research**: Large-scale movement pattern studies
- **Entertainment**: Interactive applications and games
- **Education**: Movement teaching and body awareness
## 🔗 Integration Examples
### Gradio Client
```python
from gradio_client import Client
client = Client("http://localhost:7860")
result = client.predict(
video="path/to/video.mp4",
model="mediapipe-full",
api_name="/analyze_enhanced"
)
```
### Batch Processing
```python
results = client.predict(
files=["video1.mp4", "video2.mp4"],
model="yolo-v11-s",
api_name="/batch_analyze"
)
```
""")
gr.HTML("""
<div class="author-info">
<p><strong>Created by:</strong> Csaba Bolyós (BladeSzaSza)</p>
<p style="margin: 5px 0;">
<a href="https://github.com/bladeszasza" style="color: #a8e6cf; text-decoration: none;">🔗 GitHub</a> •
<a href="https://huggingface.co/BladeSzaSza" style="color: #a8e6cf; text-decoration: none;">🤗 Hugging Face</a> •
<a href="https://www.linkedin.com/in/csaba-bolyós-00a11767/" style="color: #a8e6cf; text-decoration: none;">💼 LinkedIn</a>
</p>
<p style="font-size: 12px; opacity: 0.9;">Contact: bladeszasza@gmail.com</p>
</div>
""")
# Footer with proper attribution
gr.HTML("""
<div style="text-align: center; padding: 20px; margin-top: 30px; border-top: 1px solid #eee;">
<p style="color: #666; margin-bottom: 10px;">
🎭 Laban Movement Analysis - Complete Suite | Heavy Beta Version
</p>
<p style="color: #666; font-size: 12px;">
Created by <strong>Csaba Bolyós</strong> | Powered by MediaPipe, MoveNet & YOLO
</p>
<p style="color: #666; font-size: 10px; margin-top: 10px;">
<a href="https://github.com/bladeszasza" style="color: #40826D;">GitHub</a> •
<a href="https://huggingface.co/BladeSzaSza" style="color: #40826D;">Hugging Face</a> •
<a href="https://www.linkedin.com/in/csaba-bolyós-00a11767/" style="color: #40826D;">LinkedIn</a>
</p>
</div>
""")
return demo
if __name__ == "__main__":
demo = create_unified_demo()
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True,
favicon_path=None
)
LabanMovementAnalysis
Initialization
| name | type | default | description |
|---|---|---|---|
default_model |
str
|
"mediapipe" |
Default pose estimation model ("mediapipe", "movenet", "yolo") |
enable_visualization |
bool
|
True |
Whether to generate visualization video by default |
include_keypoints |
bool
|
False |
Whether to include raw keypoints in JSON output |
enable_webrtc |
bool
|
False |
Whether to enable WebRTC real-time analysis |
label |
typing.Optional[str][str, None]
|
None |
Component label |
every |
typing.Optional[float][float, None]
|
None |
None |
show_label |
typing.Optional[bool][bool, None]
|
None |
None |
container |
bool
|
True |
None |
scale |
typing.Optional[int][int, None]
|
None |
None |
min_width |
int
|
160 |
None |
interactive |
typing.Optional[bool][bool, None]
|
None |
None |
visible |
bool
|
True |
None |
elem_id |
typing.Optional[str][str, None]
|
None |
None |
elem_classes |
typing.Optional[typing.List[str]][
typing.List[str][str], None
]
|
None |
None |
render |
bool
|
True |
None |
User function
The impact on the users predict function varies depending on whether the component is used as an input or output for an event (or both).
- When used as an Input, the component only impacts the input signature of the user function.
- When used as an output, the component only impacts the return signature of the user function.
The code snippet below is accurate in cases where the component is used as both an input and an output.
- As output: Is passed, processed data for analysis.
- As input: Should return, analysis results.
def predict(
value: typing.Dict[str, typing.Any][str, typing.Any]
) -> typing.Any:
return value
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gradio_labanmovementanalysis-0.0.1.tar.gz.
File metadata
- Download URL: gradio_labanmovementanalysis-0.0.1.tar.gz
- Upload date:
- Size: 84.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c357282c4575834cf159824141a52f9d6fc99113c48438c70b24b0bcb41add51
|
|
| MD5 |
c01be82041e93aa37744cad63a973429
|
|
| BLAKE2b-256 |
7e2f07ad02fedc10c16bf42a7935e82a366d6f0aaaa4dd65d513ee46f32699b8
|
File details
Details for the file gradio_labanmovementanalysis-0.0.1-py3-none-any.whl.
File metadata
- Download URL: gradio_labanmovementanalysis-0.0.1-py3-none-any.whl
- Upload date:
- Size: 45.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be2e5b6f6400bb507e52ca2ac6dddf9ac3a4c73cc055c9009f4d7699e5a0ec06
|
|
| MD5 |
bf80fe5d18a3befd7b5bf10581a4d51d
|
|
| BLAKE2b-256 |
749a76c97bea7ad9923fd7e27ffb3755966c19ef0f8fc851fed8b963df5bfd11
|