Technique analysis

How to use the api and interpret the output

Technique Analysis API Documentation

Overview

The Technique Analysis Server provides a REST API for analyzing sports technique from video data. It processes video files containing human motion and returns detailed analysis results including pose estimation, technique features, and performance metrics.

Server Endpoints

Main Processing Endpoint

POST /process

Processes a video file and returns comprehensive analysis results.

Request Format

The endpoint accepts multipart/form-data with the following fields:

  • file (required): Video file (supports .mp4, .avi, .mov, .mkv)
  • metadata (required): JSON string containing analysis parameters

Metadata Parameters

{
  "uid": "unique_identifier",
  "store_data": false,
  "sport": "pickleball",
  "swing_type": "forehand_drive",
  "dominant_hand": "right",
  "player_height_mm": 1800,
  "request_id": "optional_request_id",
  "timestamp": "2025-09-26T00:09:46.122307",
  "form_session_id": "optional_session_id",
  "ball_timestamp": 1.5
}

Required Parameters:

  • uid: Unique identifier for the request
  • sport: Sport type (e.g., "pickleball", "tennis", "none")
  • swing_type: Type of swing/technique (e.g., "forehand_drive", "backhand_drive")
  • dominant_hand: Player's dominant hand ("left" or "right")
  • player_height_mm: Player height in millimeters

Optional Parameters:

  • store_data: Whether to store data to S3 (default: false)
  • ball_timestamp: Ball hit timestamp for test cases (auto-detected if not provided)
  • request_id: Optional request identifier
  • timestamp: Request timestamp
  • form_session_id: Form session identifier

Response Format

The API returns a streaming JSON response with the following structure:

{
  "status": "done",
  "uid": "unique_identifier",
  "warnings": [],
  "errors": [],
  "result": {
    "features": [...],
    "feature_categories": {...},
    "kinetic_chain": {...},
    "wrist_speed": {...}
  },
  "video_entry_2D_json": {...},
  "video_entry_3D_json": {...}
}

Supported Sports and Techniques

Pickleball

  • forehand_drive: Forehand drive technique
  • backhand_drive: Backhand drive technique (2-handed)

Response Interpretation

Status Codes

  • "processing": Video is being processed
  • "done": Analysis completed successfully
  • "error": Analysis failed
  • "failed": Critical error occurred

Result Structure

Features Array

Each feature in the features array contains:

{
  "feature_name": "leg_width_at_ball_hit",
  "feature_human_readable_name": "Leg Width at Ball Hit",
  "level": "advanced",
  "score": 85.0,
  "value": 0.8,
  "observation": "Your leg width is optimal for stability and power",
  "suggestion": "Maintain this stance width for consistent performance",
  "feature_categories": ["balance", "lower_body", "stability"],
  "highlight_joints": [15, 16],
  "highlight_limbs": {
    "left_lower_leg": [15, 13],
    "right_lower_leg": [16, 14]
  },
  "event": {
    "name": "ball_hit",
    "timestamp": 1.5,
    "frame_nr": 45
  },
  "score_ranges": {
    "beginner": [0, 40],
    "intermediate": [40, 60],
    "advanced": [60, 80],
    "professional": [80, 100]
  },
  "value_ranges": {
    "beginner": [0.0, 0.3],
    "intermediate": [0.3, 0.5],
    "advanced": [0.5, 0.7],
    "professional": [0.7, 1.0]
  }
}

Feature Categories

The feature_categories object provides aggregated statistics:

{
  "balance": {
    "average_score": 78.5,
    "feature_count": 5,
    "features": ["leg_width_at_ball_hit", "stance_stability", ...]
  },
  "power": {
    "average_score": 82.3,
    "feature_count": 3,
    "features": ["kinetic_chain_coordination", ...]
  }
}

Kinetic Chain Analysis

The kinetic_chain object contains motion analysis:

{
  "speed_dict": {
    "hip": {
      "plot_values": [0.1, 0.3, 0.8, 1.2, 0.9, ...],
      "peak_index": 3,
      "peak_speed": 1.2
    },
    "shoulder": {
      "plot_values": [0.2, 0.4, 0.9, 1.1, 0.8, ...],
      "peak_index": 3,
      "peak_speed": 1.1
    },
    "wrist": {
      "plot_values": [0.1, 0.2, 0.5, 1.5, 1.8, ...],
      "peak_index": 4,
      "peak_speed": 1.8
    }
  }
}

Pose Data

2D Pose Data (video_entry_2D_json)

Contains 2D pose estimation results:

{
  "entry_type": "video",
  "source_path": "/path/to/video.mp4",
  "annotation_format": "H36M",
  "annotation_data": [
    {
      "frame_nr": 0,
      "timestamp": 0.0,
      "instances": [
        {
          "keypoints": [[x1, y1], [x2, y2], ...],
          "confidences": [0.9, 0.8, ...],
          "bbox": [x, y, width, height],
          "box_confidence": 0.95
        }
      ]
    }
  ]
}

3D Pose Data (video_entry_3D_json)

Contains 3D pose estimation results:

{
  "entry_type": "video",
  "source_path": "/path/to/video.mp4",
  "annotation_format": "H36M",
  "annotation_data": [
    {
      "frame_nr": 0,
      "timestamp": 0.0,
      "instances": [
        {
          "keypoints": [[x1, y1, z1], [x2, y2, z2], ...],
          "confidences": [0.9, 0.8, ...],
          "bbox": [x, y, width, height],
          "box_confidence": 0.95
        }
      ]
    }
  ]
}

Usage Examples

Example 1: Basic Pickleball Forehand Analysis

curl -X POST "http://192.168.50.187:6000/process" \
  -F "file=@forehand_video.mp4" \
  -F 'metadata={"uid":"test_001","sport":"pickleball","swing_type":"forehand_drive","dominant_hand":"right","player_height_mm":1750}'

Example 2: Python Request

import requests
import json

# Prepare metadata
metadata = {
    "uid": "python_test_001",
    "sport": "pickleball",
    "swing_type": "forehand_drive",
    "dominant_hand": "right",
    "player_height_mm": 1800,
    "store_data": False
}

# Send request
with open("video.mp4", "rb") as f:
    files = {"file": ("video.mp4", f)}
    data = {"metadata": json.dumps(metadata)}
    
    response = requests.post(
        "http://192.168.50.187:6000/process",
        files=files,
        data=data,
        stream=True
    )

# Process streaming response
for line in response.iter_lines(decode_unicode=True):
    if line:
        result = json.loads(line)
        if result.get("status") == "done":
            print("Analysis completed!")
            print(f"Features found: {len(result['result']['features'])}")
            break

Error Handling

Common Error Responses

Invalid Request Format

{
  "error": "Invalid response format",
  "status": "error",
  "timestamp": "2025-09-26T00:21:44.754097",
  "uid": "webapp_b5ef741e"
}

Server Processing Error

{
  "status": "failed",
  "uid": "unique_identifier",
  "errors": ["Detailed error message"],
  "warnings": ["Warning message"]
}

Debugging Tips

  1. Check Video Quality: Ensure the video contains clear human poses
  2. Verify Parameters: Confirm sport/swing type combinations are valid
  3. Check Player Height: Use accurate height measurements in millimeters
  4. Video Duration: Ensure video includes the complete swing motion
  5. Audio Quality: For ball hit detection, ensure audio is clear

Output Files

The server also provides a ZIP file containing:

  • video_entry_2d.pb: 2D pose data in protobuf format
  • video_entry_3d.pb: 3D pose data in protobuf format
  • technique_analysis.json: Analysis results in JSON format

Performance Considerations

  • Processing Time: Typically 30-120 seconds depending on video length
  • Video Length: Recommended 3-10 seconds for optimal analysis
  • Resolution: Higher resolution videos may take longer to process
  • Frame Rate: 30fps recommended for smooth motion capture

Integration Examples

Web Application Integration

// Frontend JavaScript example
async function analyzeVideo(videoFile, metadata) {
    const formData = new FormData();
    formData.append('file', videoFile);
    formData.append('metadata', JSON.stringify(metadata));
    
    const response = await fetch('/process', {
        method: 'POST',
        body: formData
    });
    
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    
    while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        
        const chunk = decoder.decode(value);
        const lines = chunk.split('\n');
        
        for (const line of lines) {
            if (line.trim()) {
                const result = JSON.parse(line);
                if (result.status === 'done') {
                    return result;
                }
            }
        }
    }
}

Batch Processing

import os
import json
import requests
from pathlib import Path

def batch_analyze_videos(video_directory, output_directory):
    """Process multiple videos in batch"""
    
    video_files = list(Path(video_directory).glob("*.mp4"))
    results = []
    
    for video_file in video_files:
        metadata = {
            "uid": f"batch_{video_file.stem}",
            "sport": "pickleball",
            "swing_type": "forehand_drive",
            "dominant_hand": "right",
            "player_height_mm": 1800
        }
        
        try:
            with open(video_file, "rb") as f:
                files = {"file": (video_file.name, f)}
                data = {"metadata": json.dumps(metadata)}
                
                response = requests.post(
                    "http://192.168.50.187:6000/process",
                    files=files,
                    data=data,
                    stream=True
                )
                
                # Process response
                for line in response.iter_lines(decode_unicode=True):
                    if line:
                        result = json.loads(line)
                        if result.get("status") == "done":
                            results.append({
                                "video": video_file.name,
                                "result": result
                            })
                            break
                            
        except Exception as e:
            print(f"Error processing {video_file}: {e}")
    
    return results

Troubleshooting

Common Issues

  1. "Invalid response format": Usually indicates server-side processing errors
  2. Empty features array: May indicate insufficient pose data or invalid parameters
  3. Connection errors: Ensure the server is running and accessible
  4. Timeout errors: Try with shorter videos or check server resources

Debug Information

The server provides detailed debug information including:

  • Pose detection confidence scores
  • Frame count and video duration
  • Ball hit detection results
  • Processing warnings and errors

Support

For technical support or questions about the API, refer to the server logs and debug information provided in the response.

On this page