2013-03-17 9 views
21

Supponiamo che stiamo cercando per questo modello:Come trovare un modello in un'immagine usando una maschera (o trasparenza) con OpenCV e Python?

Stop http://oi48.tinypic.com/2u7q1l4.jpg

Gli angoli del nostro modello sono trasparenti, in modo che il fondo può variare, in questo modo:

Stop on moon http://i49.tinypic.com/ziw3mc.png

Stop on everest http://i45.tinypic.com/2unwxhu.png

Stop on leaves http://i48.tinypic.com/t06v7k.png

Supponendo che potremmo utilizzare la seguente maschera con il nostro modello:

Stop http://oi48.tinypic.com/2u7q1l4.jpgStop mask http://i49.tinypic.com/ogclfd.png

Sarebbe molto facile da trovare.

Quello che ho cercato:

ho cercato matchTemplate ma non supporta le maschere (per quanto ne so), e utilizzando il canale alfa (trasparenza) nel modello non raggiungere questo obiettivo, come confronta i canali alfa invece di ignorare quei pixel.

Ho anche esaminato la "regione di interesse", che ho pensato sarebbe stata la soluzione, ma con essa è possibile specificare solo un'area rettangolare. Non sono nemmeno sicuro che funzioni sul modello o meno.

Sono sicuro che è possibile farlo scrivendo il mio algoritmo, ma speravo che fosse possibile tramite. OpenCV standard per evitare di reinventare la ruota. Per non parlare, molto probabilmente sarebbe più ottimizzato del mio.

Quindi, come posso fare qualcosa di simile con OpenCV + Python?

+2

Sarebbe di grande aiuto se pubblicassi cose che hai provato. Comunque, una domanda molto interessante. –

+0

Grazie per il commento. Ho aggiunto le cose che ho provato, non pensavo che valesse la pena menzionarle. – user1973386

+1

Prova i punti chiave corrispondenti usando SIFT/SURF – Froyo

risposta

2

Una risposta alla tua domanda è convolution. Usa il modello come kernel e filtra l'immagine.

Il tappetino di destinazione avrà aree chiare e luminose in cui il modello potrebbe essere. Dovrai raggruppare i risultati (ad es. Spostamento medio).

In questo modo, si avrà un'implementazione semplicistica di Generalized Hough Transform o Template-based convolution matching.

2

Quello che ha funzionato per me l'unica volta che ho bisogno di questo è stato quello di riempire le aree "maschera" con il rumore bianco. Quindi viene effettivamente eliminato dalla correlazione durante la ricerca di corrispondenze. Altrimenti ho ottenuto, come presumo tu abbia fatto, false corrispondenze nelle aree mascherate.

4

Questo potrebbe essere ottenuto utilizzando solo la funzione matchTemplate, ma è necessaria una piccola soluzione.

Consente di analizzare le metriche predefinite (CV_TM_SQDIFF_NORMED). Secondo matchTemplate documentation le metriche predefinite assomiglia a questo

R(x, y) = sum (I(x+x', y+y') - T(x', y'))^2

Dove I è matrice dell'immagine, T è dima, R è matrice di risultato. Sommatoria è fatto su coordinate modello x' e y',

Quindi, immobili modificare questo metriche inserendo matrice peso W, che ha le stesse dimensioni T.

Q(x, y) = sum W(x', y')*(I(x+x', y+y') - T(x', y'))^2

In questo caso, impostando W(x', y') = 0 si può effettivamente fare di pixel essere ignorato. Quindi, come rendere tali metriche? Con semplice matematica:

Q(x, y) = sum W(x', y')*(I(x+x', y+y') - T(x', y'))^2 
     = sum W(x', y')*(I(x+x', y+y')^2 - 2*I(x+x', y+y')*T(x', y') + T(x', y')^2) 
     = sum {W(x', y')*I(x+x', y+y')^2} - sum{W(x', y')*2*I(x+x', y+y')*T(x', y')} + sum{W(x', y')*T(x', y')^2)} 

Così, abbiamo diviso Q metriche in albero somme separate. E tutte queste somme potrebbero essere calcolate con la funzione matchTemplate (utilizzando il metodo CV_TM_CCORR). Vale a dire

sum {W(x', y')*I(x+x', y+y')^2} = matchTemplate(I^2, W, method=2) 
sum{W(x', y')*2*I(x+x', y+y')*T(x', y')} = matchTemplate(I, 2*W*T, method=2) 
sum{W(x', y')*T(x', y')^2)} = matchTemplate(T^2, W, method=2) = sum(W*T^2) 

L'ultimo elemento è una costante, quindi, per la minimizzazione non ha alcun effetto. D'altra parte, potrei comunque essere utile vedere se il nostro modello ha una corrispondenza perfetta (se Q si avvicina a zero). Tuttavia, per l'ultimo elemento in realtà non abbiamo bisogno della funzione matchTemplate, poiché potrebbe essere calcolata direttamente.

Il pseudocodice finale assomiglia a questo:

result = matchTemplate(I^2, W, method=2) - matchTemplate(I, 2*W*T, method=2) + as.scalar(sum(W*T^2)) 

vuol davvero fare esattamente come definito? Matematicamente sì. In pratica, c'è qualche piccolo errore di arrotondamento, perché la funzione matchTemplate funziona su 32 bit in virgola mobile, ma credo che non sia un grosso problema.

Si noti che è possibile estendere l'analisi e avere equivalenti ponderati per qualsiasi metrica offerta da matchTemplate.

Questo ha funzionato davvero per me. Mi dispiace non dare il codice attuale. Sto lavorando in R, quindi, Non ho il codice in Python. Ma l'idea è un po 'frownard.

Spero che questo possa essere d'aiuto.

+1

Praticamente la tua teoria non funzionerà. Perché? Perché matchTemplate() non funziona come dice la documentazione di OpenCV. Non fa scorrere il modello sull'immagine e li confronta pixel per pixel. Se OpenCV lo facesse, sarebbero necessari 60 secondi per elaborare un'immagine di 500x500 pixel anche nel codice C++. Quello che OpenCV fa per ottimizzare la velocità è innanzitutto calcolare DFT (Fourier Transformation) dell'immagine e del modello e poi confrontarli nello spazio di Fourier. Questo rende l'esecuzione 100 volte più veloce, ma fa fallire la tua teoria. – Elmue

+0

@Elmue, grazie per la risposta, ma vorrei non essere d'accordo. Innanzitutto, CV_TM_CCORR – Vyga

+0

@Elmue, grazie per la risposta, ma vorrei non essere d'accordo. Sì, OpenCV effettua calcoli intelligenti e io posso fare rumore con gli errori di arrotondamento. Tuttavia, con la funzione 'CV_TM_CCORR' possiamo effettivamente calcolare i valori che ho elencato. Alla fine della giornata, la risposta finale dai calcoli intelligenti è come nella formula. In realtà l'ho fatto in R e ho controllato la risposta con le funzioni di forza bruta. – Vyga

1

Imagemagick 7.0.3.9 dispone ora di una funzionalità di confronto mascherata in modo da limitare la regione di corrispondenza dei modelli. Vedi http://www.imagemagick.org/discourse-server/viewtopic.php?f=4&t=31053

Inoltre, vedo che OpenCV 3.0 ora ha la corrispondenza del modello mascherato. Vedi http://docs.opencv.org/3.0.0/df/dfb/group__imgproc__object.html#ga586ebfb0a7fb604b35a23d85391329be

Tuttavia, è solo per metodo == CV_TM_SQDIFF e metodo == CV_TM_CCORR_NORMED. vedi python opencv matchTemplate is mask feature implemented?

Problemi correlati