mirror of
https://github.com/Ladebeze66/llm_ticket3.git
synced 2025-12-16 00:36:52 +01:00
102 lines
3.8 KiB
Python
102 lines
3.8 KiB
Python
# utils/ocr_utils.py
|
|
|
|
from PIL import Image, ImageEnhance
|
|
import pytesseract
|
|
import logging
|
|
import os
|
|
import io
|
|
|
|
logger = logging.getLogger("OCR")
|
|
|
|
def pretraiter_image(image_path: str) -> Image.Image:
|
|
"""
|
|
Prétraite l'image pour améliorer la qualité de l'OCR.
|
|
|
|
Args:
|
|
image_path: Chemin de l'image
|
|
|
|
Returns:
|
|
Image prétraitée
|
|
"""
|
|
try:
|
|
# Ouvrir l'image
|
|
with Image.open(image_path) as img:
|
|
# Convertir en niveaux de gris si l'image est en couleur
|
|
if img.mode != 'L':
|
|
img = img.convert('L')
|
|
|
|
# Améliorer le contraste
|
|
enhancer = ImageEnhance.Contrast(img)
|
|
img = enhancer.enhance(1.5) # Facteur de contraste 1.5
|
|
|
|
# Augmenter la netteté
|
|
enhancer = ImageEnhance.Sharpness(img)
|
|
img = enhancer.enhance(1.5) # Facteur de netteté 1.5
|
|
|
|
# Agrandir l'image si elle est petite
|
|
width, height = img.size
|
|
if width < 1000 or height < 1000:
|
|
ratio = max(1000 / width, 1000 / height)
|
|
new_width = int(width * ratio)
|
|
new_height = int(height * ratio)
|
|
img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
|
|
|
|
return img
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors du prétraitement de l'image {image_path}: {e}")
|
|
return Image.open(image_path) # Retourner l'image originale en cas d'erreur
|
|
|
|
def extraire_texte_fr(image_path: str) -> str:
|
|
"""
|
|
Effectue un OCR sur une image en langue française.
|
|
Retourne le texte brut extrait (chaîne vide si aucun texte détecté ou en cas d'erreur).
|
|
Chaque appel est isolé et tracé dans les logs.
|
|
"""
|
|
try:
|
|
if not os.path.exists(image_path) or not os.access(image_path, os.R_OK):
|
|
logger.warning(f"Image inaccessible ou introuvable: {image_path}")
|
|
return ""
|
|
|
|
logger.info(f"Traitement OCR pour {image_path}")
|
|
|
|
# Configurer pytesseract
|
|
config = '--psm 3 --oem 3' # Page segmentation mode: 3 (auto), OCR Engine mode: 3 (default)
|
|
|
|
# Prétraiter l'image
|
|
img = pretraiter_image(image_path)
|
|
logger.info(f"Image prétraitée: dimensions={img.size}, mode={img.mode}")
|
|
|
|
# Réaliser l'OCR avec fallback
|
|
try:
|
|
texte = pytesseract.image_to_string(img, lang="fra", config=config)
|
|
except Exception as ocr_err:
|
|
logger.warning(f"Première tentative OCR échouée: {ocr_err}, tentative avec image originale")
|
|
# En cas d'échec, essayer avec l'image originale
|
|
with Image.open(image_path) as original_img:
|
|
texte = pytesseract.image_to_string(original_img, lang="fra", config=config)
|
|
|
|
# Nettoyer le texte
|
|
texte = texte.strip()
|
|
|
|
# Sauvegarder l'image prétraitée pour debug si OCR réussi
|
|
if texte:
|
|
try:
|
|
debug_dir = "debug_ocr"
|
|
os.makedirs(debug_dir, exist_ok=True)
|
|
img_name = os.path.basename(image_path)
|
|
img.save(os.path.join(debug_dir, f"pretreated_{img_name}"), format="JPEG")
|
|
logger.info(f"Image prétraitée sauvegardée dans {debug_dir}/pretreated_{img_name}")
|
|
except Exception as e:
|
|
logger.warning(f"Impossible de sauvegarder l'image prétraitée: {e}")
|
|
|
|
# Journaliser le résultat
|
|
if texte:
|
|
logger.info(f"OCR réussi [{image_path}] — {len(texte)} caractères: {texte[:100]}...")
|
|
else:
|
|
logger.warning(f"OCR vide (aucun texte détecté) pour {image_path}")
|
|
|
|
return texte
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors de l'OCR de {image_path}: {e}")
|
|
return ""
|