Aller au contenu principal

OCR et Transcription de Texte dans les Images

Lire du texte dans les images

L’OCR (Optical Character Recognition) est l’un des cas d’usage les plus courants de la Vision API. Grâce aux modèles multimodaux de Mistral, vous pouvez extraire du texte depuis des photos, captures d’écran, documents scannés, factures ou reçus — sans installer de bibliothèque OCR dédiée.

Dans cette leçon, vous apprendrez à utiliser la Vision API pour la transcription de texte, avec des techniques pour améliorer la précision.

OCR simple : lire le texte visible

La manière la plus directe :

from mistralai import Mistral
import os

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

response = client.chat.complete(
    model="mistral-small-latest",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Transcrivez exactement tout le texte visible dans cette image. Ne commentez pas, ne résumez pas -- retournez uniquement le texte tel qu'il apparaît."},
                {"type": "image_url", "image_url": "https://exemple.com/document-scanne.jpg"}
            ]
        }
    ]
)

print(response.choices[0].message.content)

Le mot clé est « exactement » — sans cette instruction, le modèle a tendance à paraphraser ou résumer le contenu.

Extraire le texte d’une facture

Les factures contiennent des informations structurées (émetteur, destinataire, montants, dates) que le modèle peut identifier :

prompt_facture = """Analysez cette facture et extrayez les informations suivantes :
- Émetteur (nom, adresse, SIRET si visible)
- Destinataire (nom, adresse)
- Numéro de facture
- Date d'émission
- Date d'échéance
- Lignes de facturation (description, quantité, prix unitaire, total)
- Sous-total HT
- TVA (taux et montant)
- Total TTC

Retournez le résultat en JSON structuré."""

response = client.chat.complete(
    model="mistral-large-latest",
    messages=[
        {
            "role": "system",
            "content": "Vous êtes un expert-comptable. Extrayez les données de facturation avec précision. Retournez uniquement du JSON valide."
        },
        {
            "role": "user",
            "content": [
                {"type": "text", "text": prompt_facture},
                {"type": "image_url", "image_url": data_uri_facture}
            ]
        }
    ]
)

Transcrire des captures d’écran

Pour extraire le contenu textuel d’une interface ou d’un terminal :

import base64

def encoder_image(chemin):
    with open(chemin, "rb") as f:
        b64 = base64.standard_b64encode(f.read()).decode("utf-8")
    return f"data:image/png;base64,{b64}"

# Transcrire une capture d'écran de terminal
response = client.chat.complete(
    model="mistral-small-latest",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": "Transcrivez la sortie du terminal visible dans cette capture d'écran. Conservez le formatage et l'indentation."
                },
                {"type": "image_url", "image_url": encoder_image("captures/terminal.png")}
            ]
        }
    ]
)

Lire des reçus et tickets de caisse

Les reçus thermiques (tickets de caisse) sont souvent de mauvaise qualité. Voici comment maximiser la précision :

prompt_recu = """Lisez ce ticket de caisse et extrayez :
1. Nom du commerce
2. Date et heure
3. Liste des articles (nom, prix)
4. Sous-total
5. Mode de paiement
6. Montant total

Si un élément est illisible, indiquez [illisible].
Retournez le résultat en JSON."""

response = client.chat.complete(
    model="mistral-large-latest",  # Large pour la meilleure lecture
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": prompt_recu},
                {"type": "image_url", "image_url": encoder_image("recu-supermarche.jpg")}
            ]
        }
    ]
)

Astuce : utilisez Mistral Large 3 pour les documents de mauvaise qualité. La différence de précision avec Small est significative sur les textes flous ou partiellement lisibles.

Traitement en lot de documents

Pour traiter un dossier de documents scannés :

import json
from pathlib import Path

def ocr_document(chemin_image, modele="mistral-small-latest"):
    """Effectue l'OCR d'un document et retourne le texte."""
    response = client.chat.complete(
        model=modele,
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "Transcrivez intégralement le texte de ce document. Conservez la mise en forme (titres, paragraphes, listes)."
                    },
                    {"type": "image_url", "image_url": encoder_image(chemin_image)}
                ]
            }
        ]
    )
    return response.choices[0].message.content

# Traiter un dossier
dossier = Path("documents_scannes/")
resultats = {}

for fichier in sorted(dossier.glob("*.jpg")):
    print(f"OCR de {fichier.name}...")
    resultats[fichier.name] = ocr_document(fichier)

# Sauvegarder
with open("transcriptions.json", "w", encoding="utf-8") as f:
    json.dump(resultats, f, ensure_ascii=False, indent=2)

print(f"{len(resultats)} documents transcrits.")

Améliorer la précision de l’OCR

Plusieurs techniques améliorent les résultats :

1. Pré-traitement de l’image

from PIL import Image, ImageEnhance, ImageFilter

def pretraiter_pour_ocr(chemin):
    """Améliore une image pour l'OCR : contraste, netteté, niveaux de gris."""
    img = Image.open(chemin)

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

    # Augmenter le contraste
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(2.0)

    # Augmenter la netteté
    img = img.filter(ImageFilter.SHARPEN)

    return img

2. Prompt spécialisé par type de document

Adaptez votre prompt au type de document :

  • Formulaires : « Lisez chaque champ et sa valeur correspondante »
  • Lettres : « Transcrivez le corps de la lettre en conservant les paragraphes »
  • Tableaux : « Extrayez les données du tableau en format markdown »

Vision API vs Document AI

Pour l’OCR avancé et le parsing documentaire, Mistral propose également Document AI (OCR 3), un service spécialisé. Voici quand utiliser l’un ou l’autre :

CritèreVision APIDocument AI (OCR 3)
OCR simpleSuffisantSurqualifié
Documents complexesLimitéOptimisé
Tableaux imbriquésApproximatifPrécis
PDF multi-pagesNon supportéSupporté
Mise en page complexeBasiqueAvancée

Nous aborderons Document AI dans la leçon 12 (Prochaines étapes).

Points clés à retenir

  • La Vision API fait un OCR correct pour les cas simples (factures, captures, reçus)
  • Utilisez le mot « exactement » dans votre prompt pour éviter la paraphrase
  • Mistral Large 3 est nettement meilleur que Small pour les documents de mauvaise qualité
  • Le pré-traitement d’image (contraste, niveaux de gris) améliore les résultats
  • Pour l’OCR avancé et les PDF multi-pages, considérez Document AI (OCR 3) de Mistral