# GraphoLab — Guida ai Laboratori Guida pratica ai laboratori dimostrativi di GraphoLab sulla grafologia forense assistita dall'AI (8 lab). --- ## Panoramica La grafologia forense è l'esame scientifico della scrittura a mano e delle firme a supporto delle indagini legali. L'AI e il machine learning possono automatizzare e scalare molti compiti che gli esperti svolgono tradizionalmente in modo manuale: | Compito | Approccio AI | Applicazione Forense | |---------|-------------|----------------------| | Trascrizione di testo manoscritto | Transformer OCR (TrOCR / EasyOCR) | Lettere anonime, documenti storici | | Autenticità della firma | Siamese Neural Network (SigNet) | Assegni, contratti, testamenti | | Localizzazione firma nei documenti | Object Detection (Conditional DETR) | Pipeline di analisi documentale | | Identificazione dello scrittore | Estrazione feature + classificatore | Paternità contestata | | Analisi caratteristiche grafologiche | OpenCV + ML | Profiling, analisi comparativa | | Riconoscimento entità nominate | Classificazione token (BERT-NER) | Persone, luoghi, organizzazioni nei documenti | | OCR profondo (corsivo italiano) | Vision-Language Model (dots.ocr 1.7B) | Testamenti, corsivo, documenti complessi | --- ## Lab 01 — Introduzione: AI e Grafologia Forense **File:** `notebooks/01_intro_forensic_graphology.ipynb` Notebook in stile presentazione, senza codice eseguibile. Tratta: - Cos'è la grafologia forense e perché è importante - I limiti dell'analisi puramente manuale - Come l'AI/ML può potenziare il lavoro dell'esperto - Mappa concettuale dell'intera pipeline: acquisizione → preprocessing → analisi AI → referto forensico - Panoramica di tutti i laboratori successivi **Prerequisiti:** Nessuno. **Destinatari:** Tutti i livelli, inclusi stakeholder non tecnici. --- ## Lab 02 — Riconoscimento del Testo Manoscritto (HTR/OCR) **File:** `notebooks/02_handwritten_ocr_trocr.ipynb` Utilizza **TrOCR** (`microsoft/trocr-base-handwritten` su Hugging Face) per trascrivere automaticamente testo manoscritto da immagini. **Cosa imparerai:** - Come funziona l'OCR basato su Transformer (encoder visivo BEiT + decoder testuale RoBERTa) - Come caricare ed eseguire un modello HTR pre-addestrato tramite la libreria `transformers` - Come preprocessare immagini di testo manoscritto per il modello - Come interpretare e visualizzare l'output della trascrizione **Flusso della demo:** 1. Caricare un'immagine di testo manoscritto da `data/samples/` 2. Eseguire l'inferenza con TrOCR 3. Visualizzare l'immagine originale affiancata al testo trascritto 4. (Opzionale) Confrontare con la trascrizione di riferimento e calcolare il CER (Character Error Rate) **Casi d'uso forensi:** - Trascrizione automatica di lettere minatorie anonime - Digitalizzazione di documenti giudiziari manoscritti storici - Fase di pre-elaborazione per pipeline di identificazione dell'autore **Prerequisiti:** `transformers`, `torch`, `Pillow` ### EasyOCR vs TrOCR — Confronto architetturale L'app Gradio usa **EasyOCR** invece di TrOCR per l'inferenza interattiva. EasyOCR **non** è un Transformer — utilizza una pipeline classica CNN + RNN: | | EasyOCR | TrOCR | |---|---|---| | Architettura | CNN + BiLSTM + CTC | Transformer encoder-decoder | | Rilevamento testo | CRAFT (mappa di calore CNN) | — (input a livello di riga) | | Encoder visivo | CNN VGG-based | BEiT (Vision Transformer) | | Decoder | LSTM bidirezionale + CTC | RoBERTa | | Contesto linguistico | Limitato (LSTM locale) | Ampio (self-attention globale) | | Velocità su CPU | ~1–3 s/immagine | ~10–20 s/immagine | | Qualità corsivo italiano | Discreta | Migliore | | Memoria RAM | ~200 MB | ~400 MB | **Quando usare quale:** EasyOCR è la scelta giusta per le demo interattive (veloce, poco memoria). TrOCR — e soprattutto dots.ocr (Lab 08) — sono preferibili quando la qualità della trascrizione su corsivo italiano complesso è prioritaria. --- ## Lab 03 — Verifica dell'Autenticità della Firma **File:** `notebooks/03_signature_verification_siamese.ipynb` Utilizza una **Siamese Neural Network** (architettura SigNet) per confrontare due immagini di firme e determinare se la firma in esame è autentica o contraffatta. **Cosa imparerai:** - Il paradigma della rete siamese per il one-shot similarity learning - Come SigNet codifica le immagini di firme in vettori di feature - Come calcolare uno score di similarità (o distanza) tra due firme - Come impostare una soglia decisionale per la classificazione autentica / contraffatta **Flusso della demo:** 1. Caricare una firma di riferimento e una firma in esame da `data/samples/` 2. Estrarre gli embedding di feature con il codificatore SigNet 3. Calcolare lo score di similarità coseno 4. Visualizzare: verdetto autentica / contraffatta + score di confidenza **Casi d'uso forensi:** - Verifica di firme su assegni bancari - Autenticazione di firme su contratti, testamenti e atti legali - Rilevamento di firme tracciate o riprodotte digitalmente **Prerequisiti:** `torch`, `scikit-image`, `Pillow` **Nota:** I pesi SigNet pre-addestrati (`models/signet.pth`) sono stati addestrati sul dataset di firme **GPDS**. I campioni demo provengono dal database **CEDAR** (`data/samples/genuine_N_M.png` / `forged_N_M.png`) e sono stati pre-selezionati affinché il modello rilevi correttamente la contraffazione. **Riferimento:** [luizgh/sigver](https://github.com/luizgh/sigver) — implementazione SigNet e pesi pre-addestrati. ### Generalizzazione a firmatari non presenti nel training set SigNet utilizza il **metric learning** (rete siamese con contrastive loss), non un classificatore tradizionale. Questa è una distinzione architetturale fondamentale: - Un **classificatore** impara "chi è la persona X" — non può generalizzare a identità mai viste. - Un **modello siamese/metrico** impara "queste due firme provengono dalla stessa mano?" — la domanda è indipendente dall'identità e generalizza a qualsiasi firmatario, inclusi quelli mai visti durante il training. In pratica, SigNet può essere applicata a **qualsiasi coppia di firme**, indipendentemente dal fatto che il firmatario sia presente in GPDS o CEDAR. **Limitazioni note:** | Limitazione | Dettaglio | |---|---| | Bias culturale/stilistico | GPDS contiene principalmente firme brasiliane/portoghesi; firme italiane o non latine possono uscire dalla distribuzione di training | | Calibrazione della soglia | La soglia 0.35 (distanza coseno) è ottimizzata su CEDAR; per firmatari con stile insolitamente compatto o elaborato potrebbe richiedere aggiustamenti | | Tipo di falsificazione | Addestrato su *skilled forgeries* (il falsificatore ha praticato la firma); le performance su falsificazioni rozze sono generalmente migliori, su quelle professionali comparabili a un esperto umano | | Qualità dell'immagine | Le performance degradano con foto di documenti su carta colorata, piegata o con timbri sovrapposti | **Indicazione pratica:** Usare SigNet come **strumento di screening di primo livello**. Non è certificato per testimonianza forense legale autonoma; i risultati devono sempre essere revisionati da un esaminatore qualificato. --- ## Lab 04 — Rilevamento Firma nei Documenti (Conditional DETR) **File:** `notebooks/04_signature_detection_detr.ipynb` Utilizza un modello **Conditional DETR** fine-tuned per il rilevamento di firme (`tech4humans/conditional-detr-50-signature-detector` su Hugging Face) per localizzare automaticamente le firme all'interno di documenti scansionati. **Cosa imparerai:** - Come funziona la rilevazione di oggetti Conditional DETR nel contesto dell'analisi documentale - Come caricare un modello Hugging Face con la libreria `transformers` - Come eseguire l'inferenza su immagini di documenti e interpretare i bounding box - Come visualizzare le regioni rilevate e ritagliarle per l'elaborazione successiva **Flusso della demo:** 1. Caricare un'immagine di documento scansionato da `data/samples/` 2. Eseguire l'inferenza Conditional DETR 3. Disegnare i bounding box attorno alle firme rilevate 4. Ritagliare e salvare ciascuna firma rilevata per l'uso nel Lab 03 **Casi d'uso forensi:** - Estrazione automatica di firme da documenti legali multi-pagina - Primo passo di una pipeline: rileva → estrai → verifica - Screening di grandi archivi documentali per la presenza di firme **Prerequisiti:** `transformers`, `timm`, `opencv-python`, `Pillow` --- ## Lab 05 — Identificazione dello Scrittore **File:** `notebooks/05_writer_identification.ipynb` Confronta le caratteristiche stilistiche di un campione manoscritto anonimo con un insieme di campioni di riferimento noti per attribuire la paternità del documento. **Cosa imparerai:** - Come estrarre feature stilistiche della scrittura: HOG (Histogram of Oriented Gradients), LBP (Local Binary Patterns) e statistiche di run-length orizzontali/verticali - Come costruire una pipeline di identificazione basata su SVM con scikit-learn (`StandardScaler` + `SVC` con kernel RBF) - Come valutare l'accuratezza dell'identificazione tramite cross-validation - Come presentare i risultati come lista ordinata di autori candidati con punteggi di probabilità **Flusso della demo:** 1. Caricare il database di campioni di riferimento da `data/samples/writer_XX/` (cinque scrittori, 41 campioni ciascuno) 2. Estrarre le feature HOG + LBP + run-length da ciascun campione 3. Addestrare un classificatore SVM (`C=10`, `gamma="scale"`, `probability=True`) 4. Caricare un campione anonimo → lista ordinata di candidati con punteggi di probabilità **Casi d'uso forensi:** - Attribuzione di lettere minatorie anonime - Verifica della paternità di documenti contestati - Ricerca sulla provenienza di documenti storici **Prerequisiti:** `scikit-learn`, `scikit-image`, `Pillow`, `numpy` **Nota sul dataset:** La demo utilizza un database di scrittura sintetica in `data/samples/writer_XX/` (cinque scrittori, 41 campioni ciascuno) generato con font TTF di sistema (Ink Free, Lucida Handwriting, Segoe Print, Segoe Script, Comic Sans) per garantire stili distinti e riproducibili. Per uso in produzione, sostituire con scansioni reali di scrittura a mano. Il [IAM Handwriting Database](https://fki.tic.heia-fr.ch/databases/iam-handwriting-database) è il benchmark forense standard. --- ## Lab 06 — Analisi delle Caratteristiche Grafologiche **File:** `notebooks/06_graphological_feature_analysis.ipynb` Estrae e visualizza automaticamente le caratteristiche grafologiche di un campione di testo manoscritto utilizzando la computer vision classica e l'elaborazione del segnale. **Cosa imparerai:** - Come segmentare la scrittura in parole e caratteri con OpenCV - Come misurare: angolo di inclinazione delle lettere, spaziatura parole/caratteri, altezza e larghezza delle lettere, pressione del tratto (distribuzione dell'intensità dei pixel) - Come costruire una dashboard visiva delle metriche grafologiche - Come confrontare due campioni ed evidenziare le differenze **Flusso della demo:** 1. Caricare un'immagine di testo manoscritto da `data/samples/` 2. Pre-elaborare (binarizzare, denoisare, raddrizzare) 3. Segmentare in righe, parole e caratteri 4. Calcolare e visualizzare le metriche con annotazioni sull'immagine 5. (Opzionale) Confrontare due campioni affiancati **Casi d'uso forensi:** - Supporto alla testimonianza peritale con misurazioni oggettive e riproducibili - Rilevamento di indicatori di stress nella scrittura (variazione della pressione del tratto) - Analisi comparativa tra un campione di riferimento e un documento contestato **Prerequisiti:** `opencv-python`, `numpy`, `matplotlib`, `scipy` --- ## Lab 07 — Riconoscimento Entità Nominate (NER) **File:** `notebooks/07_named_entity_recognition.ipynb` Utilizza un modello **BERT-NER** multilingue (`Babelscape/wikineural-multilingual-ner`) per estrarre automaticamente entità nominate — persone, organizzazioni, luoghi — da qualsiasi testo. Ideale come secondo passo dopo la trascrizione HTR. **Cosa imparerai:** - Come funziona la classificazione token BERT (schema BIO) - Come caricare ed eseguire una pipeline NER multilingue tramite `transformers` - Come visualizzare gli span di entità con evidenziazione colorata - Come costruire una pipeline completa HTR → NER per l'analisi di documenti manoscritti **Flusso della demo:** 1. NER su testo italiano (es. testamento o dichiarazione) 2. NER su testo inglese (supporto multilingue) 3. Pipeline completa: immagine manoscritto → trascrizione TrOCR → estrazione entità NER 4. Analisi della distribuzione delle entità e della confidenza **Casi d'uso forensi:** - Identificare automaticamente persone, luoghi e organizzazioni in documenti manoscritti - Analizzare lettere anonime alla ricerca di nomi propri (nomi, indirizzi) - Costruire un grafo delle relazioni tra entità in un corpus documentale **Prerequisiti:** `transformers`, `torch`, `opencv-python`, `Pillow`, `matplotlib` --- ## Lab 08 — dots.ocr: OCR con Vision-Language Model **File:** `notebooks/08_dots_ocr_vlm.ipynb` Utilizza **dots.ocr** (`rednote-hilab/dots.ocr`) — un Vision-Language Model da 1,7 miliardi di parametri — per trascrivere testo manoscritto da immagini di documenti. A differenza degli OCR CNN, il componente LLM sfrutta il contesto linguistico per correggere le ambiguità visive, risultando più efficace sul corsivo italiano. **Cosa imparerai:** - Come l'OCR basato su VLM si differenzia da TrOCR ed EasyOCR (tabella comparativa delle architetture) - Come eseguire un check hardware e scegliere la configurazione di inferenza giusta (CPU / GPU) - Come caricare ed eseguire dots.ocr via `transformers` con dtype e attention adattativi - Come misurare e confrontare la qualità della trascrizione (CER) tra EasyOCR e dots.ocr **Flusso della demo:** 1. Check hardware — rileva GPU/RAM e seleziona automaticamente CPU fp32 o CUDA bf16 2. Caricamento dots.ocr da Hugging Face (~3,5 GB bf16, ~7 GB fp32) 3. Trascrizione di un campione writer_00 (immagine singola 320×140) 4. Trascrizione del documento completo `testamento_writer00.png` 5. Trascrizione di campioni reali dal dataset Lorella 6. Confronto EasyOCR vs dots.ocr affiancati + misurazione CER **Casi d'uso forensi:** - OCR di alta qualità su scrittura corsiva italiana - Documenti con tabelle, formule o layout complessi - Quando i risultati di EasyOCR non sono sufficienti per i requisiti di accuratezza forense **Prerequisiti:** `transformers>=4.49`, `qwen_vl_utils`, `torch`, `Pillow`, `psutil`, `accelerate` **Nota hardware:** Su CPU (~7 GB RAM libera), l'inferenza richiede 2–5 min per immagine. Su GPU ≥8 GB VRAM, 5–10 secondi. Non adatto a demo interattive in tempo reale — usare EasyOCR nell'app Gradio. **Installazione (una tantum — vedi cella nel notebook):** ```bash git clone https://github.com/rednote-hilab/dots.ocr.git DotsOCR pip install -e DotsOCR pip install qwen_vl_utils accelerate ``` **Riferimento:** [arxiv 2512.02498](https://arxiv.org/abs/2512.02498) — RedNote / Xiaohongshu, dic 2024. --- ## Demo Interattiva (Gradio) **File:** `app/grapholab_demo.py` Un'applicazione Gradio multi-tab accessibile da browser (completamente in italiano) che aggrega nove funzionalità AI: | Tab | Funzionalità | |-----|-------------| | OCR Manoscritto | Carica un'immagine (riga singola o multi-riga) → testo trascritto (EasyOCR) | | Verifica Firma | Carica due firme → verdetto autentica / falsa | | Rilevamento Firma | Carica un documento → immagine annotata con firme rilevate | | Riconoscimento Entità | Inserisci testo → entità evidenziate + tabella riepilogativa | | Identificazione Scrittore | Carica un campione di scrittura → lista di autori candidati con punteggi di probabilità | | Analisi Grafologica | Carica testo manoscritto → dashboard di metriche visive | | Perizia Forense Automatica | Carica documento (+ firma opzionale) → referto forense completo (7 step: rilevamento firma, HTR, NER, identificazione scrittore, grafologia, verifica firma, sintesi LLM via Ollama) | | Datazione Documenti | Carica più immagini di documenti → ordinamento cronologico per data estratta (EasyOCR + dateparser) | | Consulente Forense IA | Chatbot RAG: carica PDF/DOCX per arricchire la knowledge base, poi fai domande con risposta generata da un LLM Ollama locale | **Avvio in locale:** ```bash # Crea e attiva un virtual environment (consigliato) python -m venv .venv # Windows .venv\Scripts\activate # macOS / Linux source .venv/bin/activate pip install -r requirements.txt python app/grapholab_demo.py # Apri http://localhost:7860 ``` --- ## Esecuzione con Docker ```bash # JupyterLab su http://localhost:8888 (token: grapholab) docker compose up jupyter # Demo Gradio su http://localhost:7860 docker compose up gradio # Entrambi i servizi insieme docker compose up ``` La cache dei modelli Hugging Face è memorizzata in un volume Docker dedicato (`grapholab-hf-cache`) e condivisa tra i due servizi. I modelli vengono scaricati una sola volta. --- ## Dati di Esempio Le immagini di esempio si trovano in `data/samples/`: | File | Usato in | |------|---------| | `handwritten_text_*.png` | Lab 02, 05, 06 | | `signature_genuine_*.png` | Lab 03, 04 | | `signature_forged_*.png` | Lab 03 | | `document_with_signature_*.png` | Lab 04 | È possibile sostituire o integrare questi file con immagini proprie per sperimentare con casi reali.