| |
| """ |
| Tru-Stride: AI-Powered Horse Gait Analysis |
| HuggingFace Space Application |
| |
| This improved Gradio app provides: |
| - Better UI/UX for horse stride analysis |
| - Video processing capabilities |
| - Detailed analysis results |
| - Professional interface design |
| """ |
|
|
| import gradio as gr |
| import numpy as np |
| import cv2 |
| import tempfile |
| import os |
| import json |
| from datetime import datetime |
| import base64 |
| import io |
| from PIL import Image |
|
|
| |
| def analyze_horse_gait(video_path): |
| """ |
| Analyze horse gait from video file |
| Replace this with your actual pose classification model |
| """ |
| try: |
| |
| import time |
| time.sleep(2) |
| |
| |
| |
| results = { |
| "stride_pattern": np.random.choice(["normal", "abnormal"], p=[0.7, 0.3]), |
| "confidence": round(np.random.uniform(0.75, 0.95), 3), |
| "analysis_time": "2.3 seconds", |
| "details": "AI analysis completed using advanced pose estimation and gait classification", |
| "metrics": { |
| "stride_length": "Normal range (1.2-1.4m)" if np.random.random() > 0.3 else "Slightly reduced", |
| "gait_symmetry": "Balanced" if np.random.random() > 0.2 else "Minor asymmetry detected", |
| "timing": "Regular" if np.random.random() > 0.3 else "Irregular", |
| "energy_efficiency": round(np.random.uniform(0.7, 0.95), 2) |
| }, |
| "recommendations": generate_recommendations(np.random.choice(["normal", "abnormal"], p=[0.7, 0.3])) |
| } |
| |
| return results |
| |
| except Exception as e: |
| return { |
| "error": f"Analysis failed: {str(e)}", |
| "stride_pattern": "error", |
| "confidence": 0.0, |
| "analysis_time": "0 seconds", |
| "details": "Unable to process video", |
| "metrics": {}, |
| "recommendations": [] |
| } |
|
|
| def generate_recommendations(stride_pattern): |
| """Generate recommendations based on analysis results""" |
| if stride_pattern == "normal": |
| return [ |
| "β
Gait pattern appears healthy", |
| "π Continue regular exercise routine", |
| "π Monitor for any changes over time", |
| "π₯ Routine veterinary check recommended" |
| ] |
| else: |
| return [ |
| "β οΈ Irregular gait pattern detected", |
| "π₯ Veterinary consultation recommended", |
| "π Consider detailed biomechanical assessment", |
| "π Document any behavioral changes", |
| "π Avoid intensive training until cleared" |
| ] |
|
|
| def process_video_analysis(video_file): |
| """Main function to process video and return formatted results""" |
| if video_file is None: |
| return "Please upload a video file", "", "", "" |
| |
| try: |
| |
| results = analyze_horse_gait(video_file) |
| |
| if "error" in results: |
| return results["error"], "", "", "" |
| |
| |
| if results["stride_pattern"] == "normal": |
| main_result = f"β
**NORMAL GAIT PATTERN**\n\nConfidence: {results['confidence']*100:.1f}%" |
| result_color = "green" |
| else: |
| main_result = f"β οΈ **ABNORMAL GAIT PATTERN**\n\nConfidence: {results['confidence']*100:.1f}%" |
| result_color = "orange" |
| |
| |
| metrics_text = "## π Detailed Analysis\n\n" |
| for key, value in results["metrics"].items(): |
| metrics_text += f"**{key.replace('_', ' ').title()}:** {value}\n\n" |
| |
| metrics_text += f"**Analysis Time:** {results['analysis_time']}\n\n" |
| metrics_text += f"**Processing Details:** {results['details']}" |
| |
| |
| recommendations_text = "## π‘ Recommendations\n\n" |
| for rec in results["recommendations"]: |
| recommendations_text += f"β’ {rec}\n\n" |
| |
| |
| summary = { |
| "timestamp": datetime.now().isoformat(), |
| "analysis_results": results, |
| "video_filename": os.path.basename(video_file) if video_file else "unknown" |
| } |
| |
| return main_result, metrics_text, recommendations_text, json.dumps(summary, indent=2) |
| |
| except Exception as e: |
| error_msg = f"β **ANALYSIS ERROR**\n\nError: {str(e)}" |
| return error_msg, "", "", "" |
|
|
| |
| custom_css = """ |
| .main-container { |
| max-width: 1200px; |
| margin: 0 auto; |
| } |
| |
| .result-normal { |
| background-color: #d4edda; |
| border: 1px solid #c3e6cb; |
| border-radius: 8px; |
| padding: 15px; |
| color: #155724; |
| } |
| |
| .result-abnormal { |
| background-color: #f8d7da; |
| border: 1px solid #f5c6cb; |
| border-radius: 8px; |
| padding: 15px; |
| color: #721c24; |
| } |
| |
| .metrics-section { |
| background-color: #f8f9fa; |
| border-radius: 8px; |
| padding: 15px; |
| margin: 10px 0; |
| } |
| |
| .recommendations-section { |
| background-color: #e7f3ff; |
| border-radius: 8px; |
| padding: 15px; |
| margin: 10px 0; |
| } |
| """ |
|
|
| |
| def create_interface(): |
| with gr.Blocks(css=custom_css, title="Tru-Stride: Horse Gait Analysis") as interface: |
| |
| |
| gr.HTML(""" |
| <div style="text-align: center; margin-bottom: 30px;"> |
| <h1 style="color: #2c3e50; font-size: 2.5em; margin-bottom: 10px;"> |
| π Tru-Stride |
| </h1> |
| <h2 style="color: #7f8c8d; font-size: 1.2em; font-weight: normal;"> |
| AI-Powered Horse Gait Analysis & Stride Classification |
| </h2> |
| <p style="color: #95a5a6; margin-top: 15px;"> |
| Upload a video of your horse's movement for professional-grade gait analysis |
| </p> |
| </div> |
| """) |
| |
| with gr.Row(): |
| with gr.Column(scale=1): |
| |
| gr.HTML("<h3>πΉ Video Upload</h3>") |
| video_input = gr.Video( |
| label="Horse Movement Video", |
| height=400, |
| show_download_button=False |
| ) |
| |
| gr.HTML(""" |
| <div style="background-color: #f8f9fa; padding: 15px; border-radius: 8px; margin: 10px 0;"> |
| <h4>π Video Guidelines:</h4> |
| <ul> |
| <li><strong>Duration:</strong> 10-60 seconds recommended</li> |
| <li><strong>Quality:</strong> Clear side view of horse</li> |
| <li><strong>Lighting:</strong> Good natural or artificial lighting</li> |
| <li><strong>Gait:</strong> Walk, trot, or canter</li> |
| <li><strong>Format:</strong> MP4, MOV, AVI supported</li> |
| <li><strong>Size:</strong> Maximum 100MB</li> |
| </ul> |
| </div> |
| """) |
| |
| analyze_btn = gr.Button( |
| "π Analyze Gait Pattern", |
| variant="primary", |
| size="lg" |
| ) |
| |
| with gr.Column(scale=1): |
| |
| gr.HTML("<h3>π Analysis Results</h3>") |
| |
| result_output = gr.Markdown( |
| label="Main Result", |
| value="Upload a video and click 'Analyze Gait Pattern' to begin" |
| ) |
| |
| metrics_output = gr.Markdown( |
| label="Detailed Metrics", |
| value="" |
| ) |
| |
| recommendations_output = gr.Markdown( |
| label="Recommendations", |
| value="" |
| ) |
| |
| |
| with gr.Row(): |
| gr.HTML("<h3>π Analysis Report</h3>") |
| |
| with gr.Row(): |
| report_output = gr.Textbox( |
| label="Detailed JSON Report (for veterinarians/professionals)", |
| lines=8, |
| max_lines=15, |
| value="", |
| show_copy_button=True |
| ) |
| |
| |
| gr.HTML(""" |
| <div style="background-color: #fff3cd; border: 1px solid #ffeaa7; border-radius: 8px; padding: 15px; margin: 20px 0;"> |
| <h4 style="color: #856404;">β οΈ Important Disclaimer</h4> |
| <p style="color: #856404; margin: 0;"> |
| This AI analysis tool is for informational purposes only and does not replace professional veterinary diagnosis. |
| Always consult with a qualified veterinarian for health concerns or before making training decisions. |
| </p> |
| </div> |
| """) |
| |
| |
| analyze_btn.click( |
| fn=process_video_analysis, |
| inputs=[video_input], |
| outputs=[result_output, metrics_output, recommendations_output, report_output] |
| ) |
| |
| |
| gr.HTML(""" |
| <div style="margin-top: 30px; text-align: center;"> |
| <h3>π― About Tru-Stride</h3> |
| <p> |
| Tru-Stride uses advanced computer vision and machine learning to analyze horse movement patterns, |
| helping trainers, veterinarians, and horse owners assess gait quality and detect potential issues early. |
| </p> |
| </div> |
| """) |
| |
| return interface |
|
|
| |
| if __name__ == "__main__": |
| interface = create_interface() |
| interface.launch( |
| server_name="0.0.0.0", |
| server_port=7860, |
| share=False, |
| show_error=True |
| ) |