CalcTrainer / app.py
hoololi's picture
Upload 2 files
271b2e1 verified
raw
history blame
7.56 kB
# ==========================================
# app.py - Calcul OCR v3.0
# ==========================================
"""
Application principale - Entraînement aux calculs avec OCR
"""
import gradio as gr
import warnings
import os
import gc
import numpy as np
from PIL import Image
warnings.filterwarnings("ignore")
# Import avec structure claire : GPU ou CPU uniquement
try:
# Test GPU : torch + CUDA disponible
import torch
if torch.cuda.is_available():
from image_processing_gpu import init_ocr_model, create_white_canvas, cleanup_memory
print("📱 Interface: Mode GPU détecté - TrOCR")
else:
# Torch installé mais pas de GPU → CPU
from image_processing_cpu import init_ocr_model, create_white_canvas, cleanup_memory
print("📱 Interface: Mode CPU détecté - EasyOCR")
except ImportError:
# Torch pas installé → CPU obligatoire
from image_processing_cpu import init_ocr_model, create_white_canvas, cleanup_memory
print("📱 Interface: Mode CPU détecté - EasyOCR")
from game_engine import MathGame, export_to_clean_dataset
print("🚀 Initialisation Calcul OCR v3.0...")
print("🔄 Chargement modèle OCR...")
init_ocr_model()
print("✅ Modèle OCR prêt")
game = MathGame()
def start_game_wrapper(duration: str, operation: str, difficulty: str) -> tuple:
cleanup_memory()
return game.start_game(duration, operation, difficulty)
def next_question_wrapper(image_data: dict | np.ndarray | Image.Image | None) -> tuple:
return game.next_question(image_data)
def export_current_session() -> str:
"""Export vers le nouveau dataset calcul_ocr_dataset"""
if not hasattr(game, 'session_data') or not game.session_data:
return "❌ Aucune donnée de session à exporter"
export_info = game.get_export_status()
if export_info["status"] == "exported":
return f"""✅ Session déjà exportée !
📅 Exporté le: {export_info['timestamp'][:19].replace('T', ' ')}
📊 Résultat: {export_info['result'][:100]}...
💡 Jouez une nouvelle session pour contribuer davantage !"""
if export_info["status"] == "exporting":
return "⏳ Export en cours..."
if not export_info["can_export"]:
return "❌ Aucune donnée à exporter"
game.mark_export_in_progress()
try:
result = export_to_clean_dataset(game.session_data)
game.mark_export_completed(result)
cleanup_memory()
return result
except Exception as e:
game.export_status = "not_exported"
return f"❌ Erreur export: {str(e)}"
# Interface Gradio
with gr.Blocks(
title="🧮 Calcul OCR - Entraînement mathématiques",
theme=gr.themes.Soft(),
css="""
.gradio-container { max-width: 1200px !important; }
.config-section {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px;
border-radius: 10px;
margin: 10px 0;
}
.dataset-info {
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
color: white;
padding: 15px;
border-radius: 10px;
margin: 10px 0;
}
.radio-group {
background: #f8f9fa;
padding: 10px;
border-radius: 8px;
margin: 5px 0;
}
""",
head="<meta name='viewport' content='width=device-width, initial-scale=1.0'>"
) as demo:
gr.Markdown(
"""
# 🧮 Entraînement aux calculs avec OCR
**Nouveau !** Choisissez votre configuration et entraînez-vous sur différents types de calculs !
**Comment jouer :**
1. **Configurez** votre session ci-dessous
2. Cliquez sur **🚀 GO !** pour démarrer
3. **Écrivez** ✏️ votre réponse sur le tableau
4. Cliquez sur **➡️ NEXT !** pour la question suivante
À la fin, vous pourrez contribuer au dataset ouvert pour améliorer l'OCR mathématique !
---
"""
)
# Configuration de la session
with gr.Group():
gr.Markdown("### ⚙️ Configuration de la session", elem_classes=["config-section"])
with gr.Row():
duration_choice = gr.Radio(
choices=["30 secondes", "60 secondes"],
value="30 secondes",
label="⏱️ Durée",
elem_classes=["radio-group"]
)
operation_choice = gr.Radio(
choices=["×", "+", "-", "÷", "Aléatoire"],
value="×",
label="🔢 Opération",
elem_classes=["radio-group"]
)
difficulty_choice = gr.Radio(
choices=["Facile", "Difficile"],
value="Facile",
label="🎯 Difficulté",
elem_classes=["radio-group"]
)
with gr.Row():
with gr.Column(scale=1):
# Question
question_display = gr.HTML(
value='<div style="font-size: 2.5em; font-weight: bold; text-align: center; padding: 20px; background: linear-gradient(45deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px;">Prêt à jouer ?</div>'
)
# Contrôles
with gr.Row():
go_button = gr.Button("🚀 GO !", variant="primary", size="lg")
next_button = gr.Button("➡️ NEXT !", variant="secondary", size="lg", interactive=False)
# Status
status_display = gr.Markdown("### 🎯 Configurez votre session et cliquez sur GO !")
timer_display = gr.Markdown("### ⏱️ --")
with gr.Column(scale=1):
# Zone de dessin
canvas = gr.ImageEditor(
label="✏️ Votre réponse",
height=350,
width=350,
value=create_white_canvas(350, 350),
brush=gr.Brush(default_size=8, default_color="#000000"),
sources=[],
layers=False,
transforms=[],
eraser=gr.Eraser(default_size=20)
)
# Résultats
results_display = gr.HTML("")
# Export vers dataset dédié
gr.Markdown("### 📤 Contribuer au dataset", elem_classes=["dataset-info"])
export_button = gr.Button("📤 Ajouter la série au dataset calcul_ocr", variant="primary", size="lg")
export_status = gr.Markdown("")
# Événements
go_button.click(
fn=start_game_wrapper,
inputs=[duration_choice, operation_choice, difficulty_choice],
outputs=[question_display, canvas, status_display, timer_display, go_button, next_button, results_display]
)
next_button.click(
fn=next_question_wrapper,
inputs=[canvas],
outputs=[question_display, canvas, status_display, timer_display, go_button, next_button, results_display]
)
export_button.click(
fn=export_current_session,
outputs=[export_status]
)
if __name__ == "__main__":
print("🚀 Lancement Calcul OCR v3.0...")
print("🎯 Dataset: calcul_ocr_dataset")
print("📊 Opérations: ×, +, -, ÷, Aléatoire")
print("⚙️ Durées: 30s, 60s")
print("🎯 Difficultés: Facile, Difficile")
demo.launch(
share=False,
show_error=True,
server_name="0.0.0.0",
server_port=7860,
show_api=False,
favicon_path=None
)