feat(vwb): Remplacer EasyOCR par docTR (Mindee) pour l'OCR
docTR est plus performant et mieux maintenu. Crée un service OCR partagé (singleton paresseux) utilisé par verify_text_content et extraire_tableau, avec les mêmes signatures et fallbacks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -406,7 +406,7 @@ Retourne maintenant le JSON du tableau:"""
|
||||
|
||||
def _extraire_avec_ocr(self, image_base64: str) -> Optional[List]:
|
||||
"""
|
||||
Extrait le tableau avec OCR.
|
||||
Extrait le tableau avec OCR (docTR).
|
||||
|
||||
Args:
|
||||
image_base64: Image en base64
|
||||
@@ -415,28 +415,20 @@ Retourne maintenant le JSON du tableau:"""
|
||||
Liste de listes
|
||||
"""
|
||||
try:
|
||||
# Décoder l'image
|
||||
from PIL import Image
|
||||
from services.ocr_service import ocr_extract_words
|
||||
|
||||
image_data = base64.b64decode(image_base64)
|
||||
pil_image = Image.open(io.BytesIO(image_data))
|
||||
|
||||
# Essayer EasyOCR
|
||||
try:
|
||||
import easyocr
|
||||
import numpy as np
|
||||
words = ocr_extract_words(pil_image)
|
||||
|
||||
reader = easyocr.Reader(['fr', 'en'], gpu=True)
|
||||
img_array = np.array(pil_image)
|
||||
# Grouper par lignes (par coordonnée Y)
|
||||
return self._grouper_ocr_en_lignes(words)
|
||||
|
||||
results = reader.readtext(img_array)
|
||||
|
||||
# Grouper par lignes (par coordonnée Y)
|
||||
return self._grouper_ocr_en_lignes(results)
|
||||
|
||||
except ImportError:
|
||||
print("⚠️ EasyOCR non disponible")
|
||||
return None
|
||||
except ImportError:
|
||||
print("⚠️ docTR non disponible")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Erreur OCR: {e}")
|
||||
@@ -447,7 +439,7 @@ Retourne maintenant le JSON du tableau:"""
|
||||
Groupe les résultats OCR en lignes de tableau.
|
||||
|
||||
Args:
|
||||
results: Résultats EasyOCR [(bbox, text, conf), ...]
|
||||
results: Liste de dicts docTR [{"text", "bbox": (x1,y1,x2,y2), "confidence"}, ...]
|
||||
|
||||
Returns:
|
||||
Liste de lignes
|
||||
@@ -457,13 +449,13 @@ Retourne maintenant le JSON du tableau:"""
|
||||
|
||||
# Extraire les positions et textes
|
||||
items = []
|
||||
for bbox, text, conf in results:
|
||||
if conf < 0.3: # Ignorer basse confiance
|
||||
for word in results:
|
||||
if word["confidence"] < 0.3: # Ignorer basse confiance
|
||||
continue
|
||||
# Calculer le centre Y
|
||||
y_center = (bbox[0][1] + bbox[2][1]) / 2
|
||||
x_center = (bbox[0][0] + bbox[2][0]) / 2
|
||||
items.append({'text': text, 'x': x_center, 'y': y_center})
|
||||
x1, y1, x2, y2 = word["bbox"]
|
||||
y_center = (y1 + y2) / 2
|
||||
x_center = (x1 + x2) / 2
|
||||
items.append({'text': word["text"], 'x': x_center, 'y': y_center})
|
||||
|
||||
if not items:
|
||||
return []
|
||||
|
||||
Reference in New Issue
Block a user