Regola interattivamente i parametri di ingresso dell'algoritmo (A_min e tol) per verificare quali componenti vengono filtrati geometricamente e come il criterio di arresto tramite analisi semantica interrompe la scansione della coda.
6.14.8 EP06_08 ⚫ Segmentazione e Decodifica Reale di QRCode con OpenCV
Negli esercizi precedenti, le grandezze intermedie del pipeline di elaborazione delle immagini — come aree, perimetri, varianze e spostamenti — sono state fornite direttamente o calcolate a partire da matrici numeriche, senza la necessità di librerie specializzate di Visione Artificiale. In questo esercizio conclusivo del capitolo, questa restrizione viene rimossa intenzionalmente: verrà utilizzata la libreria OpenCV (cv2) per localizzare e decodificare un QRCode reale presente in una scena.
La proposta riproduce un flusso semplificato di sistemi impiegati nell’ispezione visiva, nell’automazione industriale e nella lettura automatica di documenti. Per mantenere l’input dei dati accessibile al contesto educativo, il caricamento dell’immagine sarà integrato nella libreria didattica morph, tramite la funzione mm.readImg.
La scena è fornita nel formato PGM ASCII (P2) e contiene un singolo QRCode valido, oltre a diversi oggetti distrattori, come rettangoli, regioni di rumore texturizzato e blocchi isolati. La segmentazione basata esclusivamente su proprietà geometriche — come area e forma approssimativamente quadrata — è necessaria per ridurre lo spazio di ricerca, ma non è sufficiente per identificare il codice corretto. La conferma finale sarà effettuata esclusivamente tramite il tentativo di decodifica utilizzando cv2.QRCodeDetector, una procedura compatibile con applicazioni reali di riconoscimento automatico.
6.14.8.1 📋 Linee Guida di Implementazione
Lettura delle dimensioni e dei parametri
Leggere, in questo ordine, tramite l’input standard:
- una riga contenente il numero di righe \(L\);
- una riga contenente il numero di colonne \(C\);
- una riga contenente i quattro parametri dell’algoritmo separati da spazio:
- soglia di binarizzazione \(T\) (intero);
- area minima \(A_{\text{min}}\) (intero);
- tolleranza di aspetto \(\text{tol}\) (reale);
- margine \(M\) (intero, in pixel).
Caricamento dell’immagine
Utilizzare la funzione didattica
f = mm.readImg(L, C)per leggere i valori \(L \times C\) dell’immagine in scala di grigi, ottenendo un array NumPy di tipouint8.Binarizzazione
Applicare una sogliatura binaria invertita utilizzando la soglia \(T\). Ogni pixel dell’immagine originale con intensità strettamente maggiore di \(T\) deve essere convertito a 255, mentre i rimanenti devono assumere il valore 0.
Rilevamento dei contorni
Estrarre i componenti connessi esterni utilizzando
cv2.findContours(...)con i parametri:cv2.RETR_EXTERNAL;cv2.CHAIN_APPROX_SIMPLE.
Filtraggio geometrico
Per ogni contorno trovato:
calcolare il rettangolo delimitatore
(x, y, w, h)tramitecv2.boundingRect;mantenere solo i candidati che soddisfano simultaneamente:
Area minima
\[ w \times h > A_{\text{min}} \]
Rapporto d’aspetto
\[ \left|\frac{w}{h}-1\right| \le \text{tol} \]
Ordinamento dei candidati
Ordinare i candidati per area del rettangolo delimitatore
\[ w \times h \]
in ordine decrescente.
In caso di parità, preservare l’ordine originariamente restituito da
cv2.findContours.Verifica tramite decodifica
Per ogni candidato, seguendo l’ordine stabilito:
- espandere il rettangolo di \(M\) pixel nelle quattro direzioni;
- limitare gli indici per rimanere all’interno dell’immagine;
- estrarre il ritaglio direttamente dall’immagine originale
f; - applicare
cv2.QRCodeDetector().detectAndDecode(...)su tale ritaglio.
Criterio di arresto
Interrompere immediatamente l’elaborazione quando il primo candidato produce una stringa decodificata non vuota.
Caso non trovato
Se nessun candidato viene decodificato con successo, stampare esattamente:
QRCODE_NAO_ENCONTRATOOutput (caso trovato)
Stampare due righe.
Prima riga:
riga colonna altezza larghezzautilizzando il rettangolo delimitatore originale, prima dell’espansione tramite il margine \(M\).Seconda riga:
testo_decodificato
6.14.8.2 📌 Vincoli Computazionali
- Utilizzare funzioni OpenCV per eseguire la binarizzazione, il rilevamento dei contorni, il calcolo del rettangolo delimitatore e la decodifica del QRCode.
- Il filtraggio geometrico deve avvenire obbligatoriamente prima della fase di decodifica.
- Utilizzare esclusivamente la soglia fissa \(T\) fornita in input. Non è consentito utilizzare metodi automatici di sogliatura, come Otsu o sogliatura adattativa.
- Garantire che i ritagli inviati al decodificatore rimangano all’interno dei limiti dell’immagine.
6.14.8.3 🧠 Fondamenti Teorici
| Fase | Ruolo nel pipeline | Conseguenza se omessa |
|---|---|---|
| Filtraggio geometrico | Riduce lo spazio di ricerca selezionando solo regioni compatibili con la geometria attesa di un QRCode. | Il decodificatore elaborerebbe tutti i contorni, inclusi rumori e oggetti distrattori. |
| Decodifica | Conferma semanticamente se il candidato contiene un QRCode valido. | Oggetti geometricamente simili potrebbero essere classificati erroneamente come QRCode. |
| Margine \(M\) | Preserva la zona di silenzio attorno al codice, facilitandone il rilevamento. | L’assenza di tale margine può impedire l’allineamento e la corretta lettura del codice. |
Questo esercizio integra concetti studiati durante il capitolo in un unico pipeline di Visione Artificiale. La segmentazione riduce l’insieme delle regioni candidate tramite caratteristiche geometriche, mentre la fase di decodifica valida il contenuto della regione utilizzando un algoritmo specializzato di riconoscimento.
6.14.8.4 📦 Specifica di Input e Output (VPL)
Struttura di Input
L
C
T A_min tol M
[matrice dell'immagine]
Struttura di Output (Successo)
riga colonna altezza larghezza
testo_decodificato
Struttura di Output (Fallimento)
QRCODE_NAO_ENCONTRATO
6.14.8.5 📌 File di Riferimento (.pgm)
A scopo di validazione, debug locale e analisi di matrici reali di pixel, i file immagine generati nel formato ASCII P2 sono disponibili nella directory del progetto. Puoi utilizzarli per testare con i decoder del tuo cellulare l’aderenza del tuo codice (salvare i *.pgm localmente per visualizzarli):
- 📥 Caso 1: Pattern Normale – Contiene un singolo codice perfettamente centralizzato con semplici distrattori geometrici alla periferia.
- 📥 Caso 2: Scenario Complesso – Presenta una maggiore densità di rumore texturizzato e molteplici candidati distrattori che mettono alla prova i limiti del filtraggio per aspetto.
- 📥 Caso 3: Messaggio Esteso – Contiene un QRCode strutturato a partire da una stringa di caratteri di lunghezza maggiore, generando una maggiore densità di moduli interni.
- 📥 Caso 4: Geometria Compatta – Valuta il comportamento del pipeline in condizioni ottimizzate di contrasto e posizionamento limite.
- 📥 Caso 5: Scenario di Esclusione – Immagine composta puramente da elementi distrattori di alta area, progettata per validare il comportamento di fallimento controllato del programma.
%%writefile EP06_08.py
# Codice PythonOverwriting EP06_08.py
TestSuite("EP06_08.py").run()✔️ EP06_08.cases esiste già in casos/
📋 5 caso/i caricato/i da casos/EP06_08.cases
🔍 Test di Python: EP06_08.py
⚠️ EP06_08.py: file vuoto (meno di 3 righe). Test saltati.