Uno dei progetti più interessanti a cui ho lavorato negli ultimi due anni è stato un progetto sull'elaborazione delle immagini . L'obiettivo era sviluppare un sistema in grado di riconoscere le "lattine" della Coca-Cola (nota che sto sottolineando la parola "lattine", vedrai perché tra un minuto). Di seguito puoi vedere un esempio, con la lattina riconosciuta nel rettangolo verde con scala e rotazione.

Alcuni vincoli al progetto:
- Lo sfondo potrebbe essere molto rumoroso.
- La lattina potrebbe avere qualsiasi scala o rotazione o persino orientamento (entro limiti ragionevoli).
- L'immagine potrebbe presentare un certo grado di sfocatura (i contorni potrebbero non essere completamente dritti).
- Nell'immagine potrebbero esserci delle bottiglie di Coca-Cola e l'algoritmo dovrebbe rilevare solo la lattina !
- La luminosità dell'immagine potrebbe variare molto (quindi non puoi fare affidamento "troppo" sul rilevamento del colore).
- La lattina potrebbe essere parzialmente nascosta ai lati o al centro e possibilmente in parte nascosta dietro una bottiglia.
- Non ci potrebbe essere alcuna possibilità nell'immagine, nel qual caso non devi trovare nulla e scrivere un messaggio dicendo così.
Quindi potresti finire con cose difficili come questa (che in questo caso il mio algoritmo ha fallito totalmente):

Ho fatto questo progetto un po 'di tempo fa e mi sono divertito molto a farlo, e ho avuto una buona realizzazione. Ecco alcuni dettagli sulla mia implementazione:
Lingua : Fatto in C ++ usando la libreria OpenCV .
Pre-elaborazione : per la pre-elaborazione dell'immagine, ovvero trasformando l'immagine in una forma più grezza da dare all'algoritmo, ho usato 2 metodi:
- Modifica del dominio del colore da RGB a HSV e filtro basato sulla tonalità "rossa", saturazione al di sopra di una certa soglia per evitare i colori di tipo arancione e filtro di basso valore per evitare i toni scuri. Il risultato finale era un'immagine binaria in bianco e nero, in cui tutti i pixel bianchi rappresentavano i pixel che corrispondono a questa soglia. Ovviamente c'è ancora molta schifezza nell'immagine, ma questo riduce il numero di dimensioni con cui devi lavorare.
- Filtro del rumore utilizzando il filtro mediano (prendendo il valore medio dei pixel di tutti i vicini e sostituendo il pixel con questo valore) per ridurre il rumore.
- Utilizzando il filtro di rilevamento dei bordi di Canny per ottenere i contorni di tutti gli elementi dopo 2 passaggi precedenti.

Algoritmo : l'algoritmo stesso che ho scelto per questo compito è stato preso da questo fantastico libro sull'estrazione di feature e chiamato Generalized Hough Transform (piuttosto diverso dalla normale Hough Transform). Fondamentalmente dice alcune cose:
- Puoi descrivere un oggetto nello spazio senza conoscere la sua equazione analitica (che è il caso qui).
- È resistente alle deformazioni dell'immagine come ridimensionamento e rotazione, in quanto testerà sostanzialmente l'immagine per ogni combinazione di fattore di scala e fattore di rotazione.
- Utilizza un modello di base (un modello) che l'algoritmo "apprenderà".
- Ogni pixel rimanente nell'immagine del contorno voterà per un altro pixel che presumibilmente sarà il centro (in termini di gravità) del tuo oggetto, in base a ciò che ha appreso dal modello.
Alla fine, finisci con una mappa di calore dei voti, ad esempio qui tutti i pixel del contorno della lattina voteranno per il suo centro gravitazionale, quindi avrai molti voti nello stesso pixel corrispondente al al centro e vedrà un picco nella mappa di calore come di seguito:

Una volta che lo hai, una semplice euristica basata su soglia può darti la posizione del pixel centrale, da cui puoi derivare la scala e la rotazione e quindi tracciare il tuo piccolo rettangolo attorno ad esso (la scala finale e il fattore di rotazione saranno ovviamente relativi al tuo modello originale). In teoria almeno ...
Risultati : ora, mentre questo approccio ha funzionato nei casi di base, in alcune aree era gravemente carente:
- È estremamente lento ! Non lo sto sottolineando abbastanza. È stato necessario quasi un giorno intero per elaborare le 30 immagini di prova, ovviamente perché avevo un fattore di ridimensionamento molto elevato per la rotazione e la traduzione, poiché alcune lattine erano molto piccole.
- Era completamente perso quando le bottiglie erano nell'immagine, e per qualche motivo quasi sempre trovava la bottiglia invece della lattina (forse perché le bottiglie erano più grandi, quindi avevano più pixel, quindi più voti)
- Anche le immagini sfocate non andavano bene, poiché i voti finivano in pixel in punti casuali intorno al centro, finendo così con una mappa di calore molto rumorosa.
- La varianza nella traduzione e nella rotazione è stata raggiunta, ma non nell'orientamento, il che significa che una lattina che non era direttamente rivolta verso l'obiettivo della fotocamera non è stata riconosciuta.
Potete aiutarmi a migliorare il mio algoritmo specifico , utilizzando esclusivamente le funzionalità OpenCV , per risolvere i quattro problemi specifici citati?
Spero che alcune persone imparino anche qualcosa da esso, dopo tutto penso che non solo le persone che fanno domande dovrebbero imparare. :)







Inoltre, guarda questo disegno che ho fatto in MS Paint ... È assolutamente orribile e abbastanza incompleto, ma basandoti solo sulla forma e sui colori, puoi indovinare quale sarà probabilmente. In sostanza, queste sono le uniche cose di cui bisogna preoccuparsi di scansionare. Quando guardi quella forma molto particolare e la combinazione di colori così vicini, cos'altro potrebbe essere? Il pezzo che non ho dipinto, lo sfondo bianco, dovrebbe essere considerato "qualcosa di incoerente". Se avesse uno sfondo trasparente, potrebbe andare su quasi tutte le altre immagini e puoi ancora vederlo.