2010-03-31 23 views
8

Compito: Ho una telecamera montata all'estremità della nostra catena di montaggio, che acquisisce le immagini degli articoli prodotti. Diciamo per esempio che noi produciamo biglietti (con testo e immagini su di essi). Quindi ogni biglietto prodotto da viene fotografato e salvato su disco come immagine. Ora I vorrebbe controllare queste immagini salvate per le anomalie (cioè confrontare con un'immagine (un modello), che è OK). Quindi, se c'è un problema con un biglietto sulla nostra catena di montaggio (immagine mancante, una macchia, ...), la mia applicazione dovrebbe trovarla (perché la sua immagine differisce troppo dal mio modello ).Confronta le immagini per trovare le differenze

Domanda: Qual è il modo più semplice per confrontare le immagini e trovare le differenze tra di loro? Devo scrivere i miei metodi, oppure posso usare quelli esistenti per ? Sarebbe bello se ho appena impostato un valore di tolleranza (vale a dire immagini possono differire per 1%), mettere entrambe le immagini in una funzione e ottenere un valore di ritorno di vere o false :)

Strumenti: C# o VB. NET, Emgu.CV (.NET wrapper per OpenCV) o qualcosa di simile

risposta

2

I' d consiglio di guardare a AForge Imaging library dato che contiene molte funzioni veramente utili per questo tipo di lavoro.

Ci sono diversi metodi è possibile utilizzare:

  1. semplice sottrazione (template di immagini - in corso) e vedere quanti pixel sono diversi. Probabilmente vorrai limitare i risultati, ad esempio includere solo pixel diversi da 10 o più (ad esempio).
  2. Se i biglietti possono spostarsi nel campo visivo, l'elemento 1) non funzionerà, a meno che non sia possibile individuare prima il biglietto. Se per esempio il biglietto è bianco su sfondo nero, potresti fare una soglia sull'immagine e questo ti darebbe una buona idea di dove fosse il biglietto.
  3. Un'altra tecnica che ho usato prima è "Model Finding" o "Pattern Matching", ma so solo una libreria commerciale Matrox Imaging Library (o MIL) che contiene queste funzioni in quanto non sono banali.

Inoltre è necessario assicurarsi di sapere quali parti del biglietto sono più importanti. Ad esempio, suppongo che un logo o filigrana mancante costituisca un grosso problema. Ma alcune aree potrebbero avere un testo variabile, come un numero seriale e quindi ti aspetteresti che siano diverse. Fondamentalmente potrebbe essere necessario trattare alcune aree dell'immagine in modo diverso dalle altre.

1

Non conosco i dettagli, ma so che in situazioni industriali in cui un throughput elevato è essenziale, questo a volte viene fatto utilizzando reti neurali. Trasformano milioni di bit (pixel della fotocamera) in 1 (buono o cattivo). Forse questo ti aiuterà nella ricerca.

3

Non conosco molto su OpenCV, ma un po 'sull'elaborazione delle immagini.

La strada da percorrere dipende dalla frequenza con cui vengono scattate nuove foto. Un approccio semplicistico sarebbe quello di calcolare un quadro diverso del modello "buono" e dell'immagine del prodotto reale.

Se le immagini sono identiche al 100%, l'immagine risultante dovrebbe essere vuota. Se ci sono pixel residui, puoi contarli e prenderli come misura di deviazione dalla norma.

Tuttavia, dovrai allineare l'orientamento (e probabilmente la scala) di una delle immagini per allineare i bordi, altrimenti questo approccio non funzionerà.

Se si dispone di vincoli di tempo, è possibile ridurre le informazioni nelle immagini prima di elaborarle (utilizzando ad esempio un rilevamento del bordo e/o convertirle in scala di grigi o bitmap monocromatico se le funzionalità del prodotto sono sufficientemente significative)

1

Ci sono sicuramente applicazioni e librerie là fuori che fanno già ciò che si sta tentando di fare, ma non ne conosco nessuna. Ovviamente, è possibile eseguire l'hash delle due immagini e confrontarle, ma ci si aspetta che le cose siano identiche a e che non lasci spazio a differenze di luce o cose del genere.

Supponendo che aveva controllato per gli oggetti nelle immagini di essere orientate in modo identico e posizionati in modo identico, una cosa che poteva Do è marciare attraverso i pixel di ogni immagine, e ottenere i valori HSV di ciascuno in questo modo:

Color color1 = Image1.GetPixel(i,j); 
Color color2 = Image2.GetPIxel(i,j); 
float hue1 = color1.GetHue(); 
float sat1 = color1.GetSaturation(); 
float bright1 = color1.GetBrightness(); 
float hue2 = color2.GetHue(); 
float sat2 = color2.GetSaturation(); 
float bright2 = color2.GetBrightness(); 

e fare alcuni confronti con quei valori. Ciò consentirebbe di confrontarli, credo, con maggiore affidabilità rispetto all'utilizzo dei valori RGB, in particolare poiché si desidera includere alcune tolleranze nel confronto.


Edit:

Solo per divertimento, ho scritto un'applicazione di esempio utilizzato poco che la mia idea di cui sopra. In sostanza, ha totalizzato il numero di pixel i cui valori H, S e V differivano di una certa quantità (ho scelto 0,1 come valore) e poi abbandonati dai circuiti di confronto se i contatori H, S o V superavano il 38400 o il 2% di i pixel (0,02 * 1600 * 1200). Nel peggiore dei casi, ci sono voluti circa 2 secondi per confrontare due immagini identiche. Quando ho confrontato le immagini in cui una era stata modificata abbastanza da superare il valore del 2%, in genere richiedeva una frazione di secondo.

Ovviamente, questo sarebbe probabilmente troppo lento se ci fossero un sacco di immagini prodotte al secondo, ma ho pensato che fosse comunque interessante.

+0

L'hash è una buona idea, ma l'analisi pixel per pixel sull'intera immagine non produrrà prestazioni ottimali a causa della quantità di pixel per immagine (si pensi a 1600 * 1200 byte o 1.875 MB in scala di grigi) – sum1stolemyname

+0

Sembra come se dipendesse dalla velocità dell'algoritmo utilizzato, poiché qualsiasi algoritmo che avrebbe dovuto riconoscere differenze superiori all'1-2% avrebbe comunque dovuto scorrere l'intero file. Forse fare una rapida sottrazione delle immagini, quindi sommare i resti. Sarebbe più veloce che potreste fare continuando a esaminare l'intera immagine. – tloflin

1

This guy here ha scritto un semplice codice Java per lo stesso problema. Non sarà difficile convertirlo in C#, immagino. Funziona bene, anche una versione più nuova e più forte può essere trovata in esso.

Problemi correlati