File size: 6,923 Bytes
547e622
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6048e44
 
 
 
 
 
 
 
547e622
 
 
 
 
 
 
 
 
 
 
 
6048e44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547e622
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6048e44
547e622
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import os
import sys
import gradio as gr
from PIL import Image
import tempfile
import json
from flask import Flask, request, jsonify
from ctransformers import AutoModelForCausalLM

# Import du module OCR
from ocr_module import process_image as ocr_process

# Chemins
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
MODEL_PATH = os.path.join(CURRENT_DIR, "models", "Mistral-7B-Instruct-v0.3.Q4_K_M.gguf")
TEMP_DIR = os.path.join(CURRENT_DIR, "temp")

# Créer le dossier temp s'il n'existe pas
if not os.path.exists(TEMP_DIR):
    os.makedirs(TEMP_DIR)

# Vérifier l'existence du modèle
if not os.path.exists(MODEL_PATH):
    print(f"ATTENTION: Le modèle n'existe pas à {MODEL_PATH}")
    print("Exécutez d'abord le script download_model.py pour copier le modèle")
    # Tenter de trouver le modèle à l'emplacement alternatif (pour le développement)
    alt_path = os.path.join(os.path.dirname(CURRENT_DIR), "models", "Mistral-7B-Instruct-v0.3.Q4_K_M.gguf")
    if os.path.exists(alt_path):
        print(f"Modèle trouvé à l'emplacement alternatif: {alt_path}")
        MODEL_PATH = alt_path
    else:
        print("Aucun modèle trouvé. L'application risque de ne pas fonctionner correctement.")

# Chargement du modèle Mistral
try:
    print(f"Chargement du modèle depuis: {MODEL_PATH}")
    model = AutoModelForCausalLM.from_pretrained(
        MODEL_PATH,
        model_type="mistral",
        local_files_only=True,
        gpu_layers=1
    )
    print("Modèle chargé avec succès")
except Exception as e:
    print(f"Erreur lors du chargement du modèle: {e}")
    model = None

# Fonction pour prétraiter et OCR une image
def process_image(image):
    try:
        # Sauvegarder l'image temporairement
        with tempfile.NamedTemporaryFile(delete=False, suffix='.png', dir=TEMP_DIR) as temp_file:
            temp_path = temp_file.name
            if isinstance(image, str):  # Si c'est un chemin
                Image.open(image).save(temp_path)
            else:  # Si c'est un objet image
                image.save(temp_path)
        
        # Appeler la fonction OCR du module
        ocr_result = ocr_process(temp_path)
        
        # Supprimer le fichier temporaire
        if os.path.exists(temp_path):
            os.remove(temp_path)
        
        return ocr_result
    except Exception as e:
        return {"error": str(e)}

# Fonction pour moderniser le texte avec Mistral
def modernize_text(text):
    try:
        if model is None:
            return {
                "status": "error",
                "error": "Modèle non disponible"
            }
            
        # Créer le prompt pour le modèle
        prompt = f"""<s>[INST] Tu es un assistant spécialisé dans la modernisation de textes anciens. 

Modernise le texte suivant en français contemporain tout en préservant son sens:



{text} [/INST]"""
        
        # Générer la réponse
        response = model(prompt, max_new_tokens=1024, temperature=0.7)
        
        return {
            "status": "success",
            "modern_text": response.strip()
        }
    except Exception as e:
        return {
            "status": "error",
            "error": str(e)
        }

# Fonction principale pour l'interface Gradio
def ocr_and_modernize(image):
    # Extraire le texte de l'image
    ocr_result = process_image(image)
    
    if "text" in ocr_result and ocr_result["text"]:
        # Moderniser le texte
        modernization_result = modernize_text(ocr_result["text"])
        
        if modernization_result["status"] == "success":
            result = {
                "Texte original": ocr_result["text"],
                "Texte modernisé": modernization_result["modern_text"]
            }
            
            # Si LaTeX est disponible
            if "latex" in ocr_result and ocr_result["latex"]:
                result["Formules LaTeX"] = ocr_result["latex"]
                
            # Ajouter la méthode OCR utilisée
            if "ocr_method" in ocr_result:
                result["Méthode OCR"] = ocr_result["ocr_method"]
                
            # Ajouter la confiance OCR
            if "confidence" in ocr_result:
                result["Confiance OCR"] = f"{ocr_result['confidence']:.2f}%"
                
            return result
        else:
            return {
                "Texte original": ocr_result["text"],
                "Erreur": f"Échec de la modernisation: {modernization_result.get('error', 'Erreur inconnue')}"
            }
    else:
        return {
            "Erreur": f"Échec de l'OCR: {ocr_result.get('error', 'Aucun texte détecté')}"
        }

# Interface Gradio
with gr.Blocks(title="OCR et Modernisation de Texte") as demo:
    gr.Markdown("# OCR et Modernisation de Texte")
    gr.Markdown("Téléchargez une image contenant du texte pour extraire et moderniser son contenu.")
    
    with gr.Row():
        with gr.Column():
            input_image = gr.Image(type="pil", label="Image à analyser")
            submit_btn = gr.Button("Analyser l'image", variant="primary")
        
        with gr.Column():
            output = gr.JSON(label="Résultats")
            
    submit_btn.click(fn=ocr_and_modernize, inputs=input_image, outputs=output)
    
    gr.Examples(
        examples=["exemple1.jpg", "exemple2.jpg"] if os.path.exists("exemple1.jpg") else [],
        inputs=input_image
    )

# API Flask pour intégration
app = Flask(__name__)

@app.route("/api/ocr", methods=["POST"])
def api_ocr():
    if "image" not in request.files:
        return jsonify({"error": "Aucune image n'a été fournie"}), 400
    
    file = request.files["image"]
    temp_path = os.path.join(TEMP_DIR, "temp_" + str(hash(file.filename)) + ".png")
    file.save(temp_path)
    
    try:
        # Extraire le texte
        ocr_result = process_image(temp_path)
        
        # Moderniser le texte
        if "text" in ocr_result and ocr_result["text"]:
            modernization_result = modernize_text(ocr_result["text"])
            if modernization_result["status"] == "success":
                ocr_result["original_text"] = ocr_result["text"]
                ocr_result["text"] = modernization_result["modern_text"]
                
        return jsonify(ocr_result)
    except Exception as e:
        return jsonify({"error": str(e)}), 500
    finally:
        # Nettoyer
        if os.path.exists(temp_path):
            os.remove(temp_path)

# Point d'entrée
if __name__ == "__main__":
    # Si exécuté sur HF Spaces, utiliser Gradio
    if os.environ.get("SPACE_ID"):
        demo.launch()
    else:
        # En local, démarrer le serveur Flask
        app.run(host="0.0.0.0", port=7860, debug=True)