0Pricing
AI Agents · Lezione

OCR per documenti scansionati

Tesseract tramite pytesseract, preprocessing delle immagini e miglioramento dell’accuratezza

OCR per documenti scansionati è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.

Quando è necessario l'OCR

Non tutti i documenti sono PDF nativi digitali. I documenti scansionati, le fotografie di testi, gli appunti scritti a mano e i PDF basati su immagini richiedono il riconoscimento ottico dei caratteri (OCR) per estrarre il testo.

L'OCR converte le immagini composte da pixel contenenti testo in caratteri leggibili dalle macchine. Due importanti librerie Python sono: pytesseract (Google Tesseract) e EasyOCR (apprendimento profondo e supporto multilingue).

Nozioni di base su pytesseract

pytesseract è un wrapper Python per il motore OCR Tesseract di Google. Installi prima Tesseract (a livello di sistema operativo), quindi esegua pip install pytesseract Pillow.

import pytesseract
from PIL import Image

# Simple text extraction
image = Image.open('scanned_document.png')
text = pytesseract.image_to_string(image)
print(text)

# Specify language (default: English)
text_fr = pytesseract.image_to_string(
    Image.open('french_doc.png'),
    lang='fra'
)

# Get detailed output with bounding boxes
data = pytesseract.image_to_data(
    image,
    output_type=pytesseract.Output.DICT
)
for i, word in enumerate(data['text']):
    if word.strip():
        conf = data['conf'][i]
        print(f'Word: {word!r:20} Confidence: {conf}')

Preelaborazione delle immagini: scala di grigi

La precisione dell'OCR dipende in larga misura dalla qualità dell'immagine. Il primo passaggio di preelaborazione consiste nella conversione in scala di grigi: il colore aggiunge rumore senza migliorare il riconoscimento dei caratteri.

Utilizzi Pillow o OpenCV per la preelaborazione. La scala di grigi riduce il rumore e migliora il rilevamento dei bordi dei caratteri da parte di Tesseract.

from PIL import Image, ImageOps
import numpy as np

def preprocess_grayscale(image_path):
    img = Image.open(image_path)

    # Convert to grayscale
    img = img.convert('L')  # 'L' = 8-bit grayscale

    # Optionally resize for better OCR (Tesseract works best at ~300 DPI)
    # Scale up small images
    width, height = img.size
    if width < 800:
        scale = 800 / width
        new_size = (int(width * scale), int(height * scale))
        img = img.resize(new_size, Image.LANCZOS)

    return img

img = preprocess_grayscale('scan.jpg')
text = pytesseract.image_to_string(img)
print(text[:300])

Preelaborazione delle immagini: sogliatura

La sogliatura converte un'immagine in scala di grigi in un'immagine completamente in bianco e nero. In questo modo elimina le ombre grigie, l'illuminazione non uniforme e il rumore dello sfondo, facendo risaltare nettamente il testo per l'OCR.

from PIL import Image, ImageFilter
import numpy as np

def apply_threshold(img):
    # Method 1: Simple fixed threshold
    img_array = np.array(img)
    threshold = 128
    binary = np.where(img_array > threshold, 255, 0).astype(np.uint8)
    return Image.fromarray(binary)

def adaptive_threshold(img):
    # Method 2: Otsu's method via OpenCV (better for uneven lighting)
    try:
        import cv2
        img_array = np.array(img)
        _, binary = cv2.threshold(
            img_array, 0, 255,
            cv2.THRESH_BINARY + cv2.THRESH_OTSU
        )
        return Image.fromarray(binary)
    except ImportError:
        return apply_threshold(img)

img = preprocess_grayscale('uneven_scan.png')
img_clean = adaptive_threshold(img)
text = pytesseract.image_to_string(img_clean)
print(text[:300])

Preelaborazione delle immagini: raddrizzamento

I documenti scansionati sono spesso leggermente ruotati. Anche un'inclinazione di 2 gradi riduce significativamente la precisione dell'OCR. Il raddrizzamento rileva e corregge l'angolo di rotazione prima di passare l'immagine al motore OCR.

import numpy as np
from PIL import Image

def deskew(img):
    try:
        import cv2
        img_array = np.array(img)

        # Find rotation angle using Hough line transform
        edges = cv2.Canny(img_array, 50, 150, apertureSize=3)
        lines = cv2.HoughLines(edges, 1, np.pi/180, threshold=100)

        if lines is None:
            return img  # no lines detected, return unchanged

        angles = []
        for line in lines:
            rho, theta = line[0]
            angle = np.degrees(theta) - 90
            if -45 < angle < 45:
                angles.append(angle)

        if not angles:
            return img

        median_angle = np.median(angles)
        if abs(median_angle) > 0.5:  # only deskew if significant tilt
            print(f'Deskewing by {median_angle:.2f} degrees')
            return img.rotate(-median_angle, expand=True, fillcolor=255)
        return img
    except ImportError:
        return img  # OpenCV not available — skip deskew

Opzioni per le lingue di Tesseract

Tesseract supporta più di 100 lingue. Scarichi i pacchetti linguistici utilizzando il gestore dei pacchetti del sistema operativo. Per i documenti multilingue, specifichi più lingue separandole con +.

import pytesseract
from PIL import Image

# List available languages
import subprocess
result = subprocess.run(['tesseract', '--list-langs'], capture_output=True, text=True)
print('Available languages:')
print(result.stdout)

# Single language
text_en = pytesseract.image_to_string(Image.open('doc.png'), lang='eng')

# Multiple languages (auto-detect best match)
text_multi = pytesseract.image_to_string(
    Image.open('doc.png'),
    lang='eng+fra+deu'  # English + French + German
)

# Tesseract config options for better accuracy
custom_config = r'--oem 3 --psm 6'  # OEM 3=LSTM, PSM 6=assume uniform block of text
text_tuned = pytesseract.image_to_string(
    Image.open('doc.png'),
    config=custom_config
)

EasyOCR: basato sull'apprendimento profondo

EasyOCR utilizza modelli di apprendimento profondo e supera Tesseract sulle immagini degradate, sul testo curvo e sugli alfabeti non latini. Non richiede un'installazione a livello di sistema operativo.

Lo installi con pip install easyocr. Al primo avvio vengono scaricati i pesi del modello (circa 200 MB).

import easyocr

# Initialize reader (downloads model on first run)
reader = easyocr.Reader(
    ['en', 'tr'],  # list of languages
    gpu=False       # set True if CUDA available
)

# Read text from image
results = reader.readtext('scanned_page.png')

for (bbox, text, confidence) in results:
    print(f'Text: {text!r:30} Confidence: {confidence:.2f}')
    # bbox = [[x1,y1],[x2,y2],[x3,y3],[x4,y4]] (four corners)

# Get plain text only
text_only = ' '.join(result[1] for result in results)
print('Full text:', text_only[:300])

EasyOCR per documenti multilingue

EasyOCR gestisce bene i documenti con lingue miste, utili per contratti internazionali, articoli di ricerca con didascalie in più lingue o documenti con termini tecnici scritti in un alfabeto diverso.

import easyocr

# For Arabic-English mixed document
reader_ar = easyocr.Reader(['ar', 'en'], gpu=False)
results = reader_ar.readtext('arabic_contract.png')

# For CJK languages
reader_cjk = easyocr.Reader(['ch_sim', 'en'], gpu=False)  # Simplified Chinese + English
results_cjk = reader_cjk.readtext('chinese_report.png')

# Filter by confidence threshold
HIGH_CONFIDENCE = 0.7
def filter_confident_results(results, threshold=HIGH_CONFIDENCE):
    return [
        (bbox, text, conf)
        for bbox, text, conf in results
        if conf >= threshold
    ]

Pipeline completa di preelaborazione

Concateni tutti i passaggi di preelaborazione, ovvero conversione in scala di grigi, sogliatura e raddrizzamento, in un'unica funzione di pipeline. Esegua l'OCR sull'immagine ripulita e restituisca sia il testo sia le metriche di affidabilità.

import pytesseract
from PIL import Image

def ocr_pipeline(image_path, lang='eng', engine='tesseract'):
    print(f'Processing: {image_path}')

    # 1. Load
    img = Image.open(image_path)

    # 2. Preprocess
    img = img.convert('L')         # grayscale
    img = adaptive_threshold(img)  # binarize
    img = deskew(img)              # correct rotation

    # 3. OCR
    if engine == 'easyocr':
        reader = easyocr.Reader([lang], gpu=False)
        results = reader.readtext(image_path)
        text = ' '.join(r[1] for r in results if r[2] > 0.5)
    else:
        config = f'--oem 3 --psm 6 -l {lang}'
        text = pytesseract.image_to_string(img, config=config)

    # 4. Clean
    text = '\n'.join(
        line.strip() for line in text.splitlines()
        if line.strip()
    )
    return text

text = ocr_pipeline('invoice_scan.jpg')
print(text[:500])

Gestire i PDF basati su immagini

Alcuni PDF contengono pagine scansionate memorizzate come immagini all'interno del contenitore PDF. Rilevi questi «PDF immagine» e applichi l'OCR pagina per pagina, utilizzando PyMuPDF per estrarre prima le immagini.

import fitz
from PIL import Image
import io
import pytesseract

def is_image_pdf(doc):
    # Check if first page has very little extractable text
    text = doc[0].get_text().strip()
    return len(text) < 50

def ocr_pdf(filepath):
    doc = fitz.open(filepath)
    if not is_image_pdf(doc):
        # Native text — no OCR needed
        return '\n'.join(doc[i].get_text() for i in range(len(doc)))

    print('Image PDF detected — running OCR')
    all_text = []

    for page_num in range(len(doc)):
        page = doc[page_num]
        # Render page as image at 300 DPI
        mat = fitz.Matrix(300/72, 300/72)  # scale to 300 DPI
        pix = page.get_pixmap(matrix=mat)
        img = Image.open(io.BytesIO(pix.tobytes('png')))
        text = pytesseract.image_to_string(img)
        all_text.append(f'--- Page {page_num+1} ---\n{text}')

    doc.close()
    return '\n'.join(all_text)

Filtraggio in base all'affidabilità e post-elaborazione

L'output dell'OCR contiene errori, soprattutto nelle immagini degradate. Esegua una post-elaborazione del testo filtrando le parole con bassa affidabilità, correggendo gli errori OCR comuni (0 invece di O, 1 invece di l) e normalizzando gli spazi.

import re

COMMON_OCR_ERRORS = {
    r'\b0([a-z])\b': r'O\1',
    r'\bl([0-9])\b': r'1\1',
    r'\|': 'I',
    r'  +': ' ',
}

def post_process_ocr(text):
    for pattern, replacement in COMMON_OCR_ERRORS.items():
        text = re.sub(pattern, replacement, text)
    lines = [line.strip() for line in text.splitlines()]
    return '\n'.join(line for line in lines if line)

def high_confidence_ocr(words_with_conf, min_confidence=60):
    words = [w for w, conf in words_with_conf if w.strip() and conf >= min_confidence]
    return post_process_ocr(' '.join(words))

fake_ocr_output = [('0range', 90), ('|s', 40), ('l5', 85), ('good', 95)]
print(high_confidence_ocr(fake_ocr_output))

Verifica delle conoscenze

Qual è lo scopo dell'applicazione di una soglia (binarizzazione) a un'immagine prima dell'OCR?

Riepilogo: OCR per documenti scansionati

L'OCR converte le immagini scansionate in testo leggibile dalle macchine. pytesseract è un wrapper di Google Tesseract: è veloce, maturo e dispone di più di 100 pacchetti linguistici. EasyOCR utilizza l'apprendimento profondo e gestisce meglio le immagini degradate e il testo multilingue.

Esegua sempre la preelaborazione: converta l'immagine in scala di grigi, applichi la sogliatura di Otsu per la binarizzazione e la raddrizzi per correggere la rotazione. Per i PDF basati su immagini, esegua il rendering delle pagine come immagini ad alta risoluzione con PyMuPDF, quindi esegua l'OCR. Filtri i risultati in base a una soglia di affidabilità per escludere il rumore.

Domande Frequenti

La lezione «OCR per documenti scansionati» è gratuita?

Sì — il testo completo di «OCR per documenti scansionati» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.

Cosa imparerò in «OCR per documenti scansionati»?

Tesseract tramite pytesseract, preprocessing delle immagini e miglioramento dell’accuratezza Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Agents?

Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «OCR per documenti scansionati»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Agents?

Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Parsing dei PDF con PyMuPDF e pdfplumber
  2. OCR per documenti scansionati
  3. Agenti Q&A su più documenti
  4. Classificazione e instradamento dei documenti
← Torna a AI Agents