Aller au contenu principal

Optimiser la précision de l'OCR

La qualité en entrée détermine la qualité en sortie

Comme le rappelait l’équipe Mistral lors de leur webinaire Document AI : c’est du « garbage in, garbage out ». La qualité de l’extraction OCR dépend directement de la qualité du document source. Dans cette leçon, vous apprendrez les techniques pour maximiser la précision de vos extractions.

Qualité d’image et résolution

Résolution minimale recommandée

Pour des résultats optimaux :

  • Documents imprimés : 200 DPI minimum, 300 DPI recommandé
  • Écriture manuscrite : 300 DPI minimum
  • Tableaux complexes : 300 DPI recommandé
  • Documents historiques : 400 DPI ou plus

Pré-traitement des images

Avant d’envoyer un document à l’API, appliquez ces corrections si nécessaire :

from PIL import Image, ImageEnhance, ImageFilter
import io
import base64

def pre_traiter_image(chemin_image: str) -> str:
    """Pré-traite une image pour améliorer l'extraction OCR."""
    img = Image.open(chemin_image)

    # 1. Conversion en niveaux de gris
    img = img.convert("L")

    # 2. Augmentation du contraste
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(1.5)

    # 3. Augmentation de la netteté
    img = img.filter(ImageFilter.SHARPEN)

    # 4. Binarisation (seuillage)
    img = img.point(lambda x: 0 if x < 128 else 255, "1")

    # Conversion en base64
    buffer = io.BytesIO()
    img.save(buffer, format="PNG")
    return base64.b64encode(buffer.getvalue()).decode("utf-8")

Correction de l’orientation

Les documents scannés sont souvent mal orientés. Corrigez l’angle avant l’envoi :

from PIL import Image

def corriger_orientation(chemin_image: str) -> Image.Image:
    """Corrige l'orientation d'une image scannée via les métadonnées EXIF."""
    img = Image.open(chemin_image)

    # Utilisation des données EXIF pour corriger l'orientation
    try:
        exif = img._getexif()
        if exif:
            orientation = exif.get(274)  # Tag EXIF orientation
            rotations = {3: 180, 6: 270, 8: 90}
            if orientation in rotations:
                img = img.rotate(rotations[orientation], expand=True)
    except (AttributeError, KeyError):
        pass

    return img

Optimisation par type de document

Documents imprimés standards

Pour les factures, contrats et rapports :

# Configuration optimale pour documents imprimés
ocr_response = client.ocr.process(
    model="mistral-ocr-latest",
    document={
        "type": "document_base64",
        "document_base64": document_base64
    },
    table_format="markdown"  # Extraction explicite des tableaux
)

Documents manuscrits

L’écriture manuscrite nécessite plus de soin :

  • Utilisez des scans de haute résolution (300+ DPI)
  • Augmentez le contraste entre l’encre et le papier
  • Évitez la binarisation agressive qui peut effacer les traits fins
  • Le modèle gère bien les écritures manuscrites multilingues

Scans de mauvaise qualité

Pour les documents dégradés :

from PIL import Image, ImageFilter, ImageEnhance

def ameliorer_scan(chemin: str) -> Image.Image:
    """Améliore un scan de mauvaise qualité."""
    img = Image.open(chemin)

    # Réduction du bruit
    img = img.filter(ImageFilter.MedianFilter(size=3))

    # Augmentation du contraste
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(2.0)

    # Augmentation de la luminosité si trop sombre
    enhancer = ImageEnhance.Brightness(img)
    img = enhancer.enhance(1.2)

    return img

Traitement par lots (Batch)

Pour traiter de gros volumes, utilisez le service Batch Inference de Mistral :

import os
import json
from pathlib import Path
from mistralai import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

def traiter_dossier(dossier: str) -> dict:
    """Traite tous les PDF d'un dossier."""
    resultats = {}
    chemin = Path(dossier)

    for fichier in chemin.glob("*.pdf"):
        print(f"Traitement de {fichier.name}...")

        with open(fichier, "rb") as f:
            import base64
            doc_b64 = base64.b64encode(f.read()).decode("utf-8")

        try:
            response = client.ocr.process(
                model="mistral-ocr-latest",
                document={
                    "type": "document_base64",
                    "document_base64": doc_b64
                },
                table_format="markdown"
            )

            resultats[fichier.name] = {
                "pages": len(response.pages),
                "contenu": "\n\n".join(
                    p.markdown for p in response.pages
                )
            }
        except Exception as e:
            resultats[fichier.name] = {"erreur": str(e)}

    return resultats

Vérification de la qualité

Après extraction, validez la qualité avec des heuristiques simples :

def verifier_qualite(markdown: str) -> dict:
    """Vérifie la qualité d'une extraction OCR."""
    indicateurs = {
        "longueur": len(markdown),
        "mots": len(markdown.split()),
        "lignes_vides_ratio": markdown.count("\n\n") / max(len(markdown), 1),
        "caracteres_speciaux_ratio": sum(
            1 for c in markdown if not c.isalnum() and c not in " \n\t.,;:!?-"
        ) / max(len(markdown), 1),
    }

    # Alertes
    if indicateurs["mots"] < 10:
        indicateurs["alerte"] = "Très peu de texte extrait"
    elif indicateurs["caracteres_speciaux_ratio"] > 0.3:
        indicateurs["alerte"] = "Ratio élevé de caractères spéciaux"

    return indicateurs

Bonnes pratiques récapitulatives

  • Résolution : 300 DPI minimum pour tout document non trivial
  • Contraste : augmentez le contraste avant l’envoi si le document est pâle
  • Orientation : corrigez l’angle de rotation des scans
  • Format : préférez PDF natif quand disponible (meilleure qualité que les scans)
  • Tableaux : utilisez table_format="markdown" ou "html" explicitement
  • Batch : traitez par lots pour les gros volumes et parallélisez les appels
  • Validation : vérifiez systématiquement la qualité de l’extraction

Points clés à retenir

  • La qualité du document source est le facteur principal de précision
  • Le pré-traitement d’image (contraste, netteté, binarisation) améliore les résultats
  • Adaptez votre approche au type de document (imprimé, manuscrit, dégradé)
  • Utilisez le batch processing pour les gros volumes
  • Validez toujours la qualité de l’extraction avant exploitation