Corrispondenza e trasparenza dei modelli OpenCV

In che modo OpenCV gestisce la trasparenza dell’immagine durante la corrispondenza dei modelli?

Il problema è che l’immagine modello deve avere parti trasparenti, perché nell’immagine originale potrebbe esserci qualcosa in quei luoghi.

Ho provato tutti i metodi e nessuno di questi ha prodotto risultati positivi (ad es. La posizione del modello nell’immagine originale non è stata rilevata correttamente).

Modifica: OK, vedo che è necessario fornire esempi.

Immagine originale

Immagine modello

Come puoi vedere, è quasi imansible abbinare questo modello a un’immagine del genere. Lo “sfondo” intorno all’object potrebbe avere qualsiasi colore (come questo, o bianco, marrone …)

Sobel sull’immagine e modello grayscaled + cvConvertScaleAbs

Immagine originale aggiuntiva

Modifica 2: la soluzione di misha funziona anche con un po ‘di ostacoli (la “trasparenza” funziona). Esempio:

Template match riuscito

Modifica 3: più occorrenze:

Ho trovato una soluzione rapida e sporca per trovare più occorrenze di un modello, ma quando il modello non viene trovato ottengo un “lotto” di falsi positivi. Principalmente a causa della mia implementazione:

  • itera su dati immagine
  • if (imageData [y, x, 0]> = maxValue * 0.95f) allora conta [x, y] come una corrispondenza (maxValue è di cvMinMaxLoc)

Funziona per le immagini, quando c’è almeno una corrispondenza positiva, tuttavia i risultati in una situazione terribile per le immagini, su cui non esiste tale modello .

Non sembra che OpenCV gestisca l’alpha nel modo desiderato.

Hai due opzioni:

  1. Scrivi il tuo metodo di correlazione incrociata che utilizzerà il canale alfa
  2. Trasforma le tue immagini in modo che il tuo canale alfa diventi irrilevante

Poiché la prima opzione è semplice, esplorerò la seconda opzione qui. Ho intenzione di riutilizzare il codice di esempio che ho fornito a una domanda simile in precedenza. Se si applica la correlazione incrociata direttamente alle immagini, lo sfondo interferisce con la corrispondenza del modello (in particolare, le parti dello sfondo chiare). Se giochi con i canali di colore, troverai che la corrispondenza nel canale blu dà il risultato corretto. Questo dipende dal contenuto dell’immagine e non è un modo coerente per risolvere il problema.

Un’altra opzione è quella di eseguire il rilevamento dei bordi (ad es. Sobel ) sull’immagine e il modello e quindi eseguire la correlazione incrociata. Ecco le immagini rilevate ai bordi (ho usato il rilevatore di bordi Sobel sul canale Luma in GIMP, e poi un certo allungamento dell’intensità).

carta geografica

costruzione

Come potete vedere, il canale alfa qui è diventato irrilevante, poiché la maggior parte del terreno è diventato a intensità zero e non contribuirà al calcolo della correlazione incrociata. Quindi ora la correlazione incrociata può essere applicata direttamente, dando il risultato desiderato:

[email protected]:~/Desktop/stackoverflow$ python cross-correlation.py map-blue.png building-maskz-blue.png (163, 244) 

Infine, ecco un’altra domanda correlata .

PS. Che gioco è questo?

Ho una soluzione un po ‘più cerebrale a questo problema che sembra funzionare abbastanza bene: Sostituisci il canale alfa dell’immagine del modello con il rumore, che rende più o meno statisticamente insignificanti le regioni trasparenti durante il processo di abbinamento.

Ad esempio, il mio caso d’uso riguardava la ricerca di caratteri emoji nelle catture di schermo da iOS. Lo sfondo della tastiera iOS cambia i colors in base al contesto, il che rende problematico il processo di corrispondenza se si esegue il commit su un particolare colore di sfondo nell’immagine modello.

Ecco l’immagine modello raw su alfa:
immagine modello grezzo su alfa

Ecco il modello elaborato con il riempimento del rumore per il canale alfa:
inserisci la descrizione dell'immagine qui

Ho inviato l’immagine del modello elaborato tramite il codice di esempio Template Matching fornito nella documentazione di OpenCV. Su uno sfondo scuro o chiaro, la partita viene trovata con ragionevole sicurezza.

Ricerca su sfondi scuri:

abbinato al buio

Ricerca su sfondi chiari:

abbinato alla luce

In confronto, lasciare trasparente il canale alfa del modello, o impegnarsi in uno sfondo scuro o chiaro, non ha restituito corrispondenze accettabili.

OpenCV 3.0 offre supporto nativo per la corrispondenza dei modelli con i modelli mascherati. Fare riferimento alla nuova documentazione :

parametri:

Immagine …

templ …

risultato …

metodo …

maschera Maschera del modello cercato. Deve avere lo stesso tipo di dati e dimensioni con templ. Non è impostato di default.

[Leggera digressione]

Notare che il modello che corrisponde alle immagini di riferimento mascherate (l’immagine più grande) non è tuttavia ansible. E questo ha senso, dato che OpenCV utilizza la corrispondenza dei modelli basati su FFT.

Pertanto, se è necessario eseguire la corrispondenza dei modelli solo in regioni specifiche delle immagini di riferimento, sarà necessario implementare il proprio metodo o mascherare l’output di cv :: matchTemplate.

L’implementazione da zero dovrebbe compensare i casi in cui si desidera solo cercare il modello in regioni molto specifiche (ad esempio, intorno agli angoli di harris).

L’opzione SQDIFF/SQDIFF_N sarebbe una soluzione se si tentasse di sostituire il canale alfa con il colore RGB nero. Almeno questa era la mia soluzione allo stesso problema. Dal mio risultato è ovvio che questo metodo è sensibile a valori di pixel più luminosi, e ne ho approfittato.

Penso che tu stia cercando di fare ciò che in OpenCV è chiamato template matching con una maschera. Penso che potresti provare a impostare una ROI (regione di interesse) sul modello. Questa domanda SO mostra come farlo . (nota che in quella domanda la ROI è impostata sull’immagine di destinazione, non il modello, ma la procedura è la stessa).

Non sono sicuro, ma il canale di trasparenza viene trattato come qualsiasi altro canale. Se un pixel in un modello è “trasparente”, dovrebbe essere “trasparente” anche sull’immagine principale. Sto solo indovinando qui.

Ho trovato lo stesso problema e ho pensato a una soluzione. Assumendo che referenceImageMask e templateMask abbiano 1s nei buoni pixel e 0 in quelli cattivi. E quel referenceImage e templateImage sono già stati mascherati e hanno lo 0 anche nei pixel difettosi.

Quindi, il primo risultato della corrispondenza del modello darà la correlazione incrociata non normalizzata tra le immagini. Tuttavia, un mucchio di pixel era zero.

La seconda corrispondenza del modello darà per ogni ansible scostamento il numero di pixel che erano allo stesso tempo diversi da zero (non mascherato) in entrambe le immagini.

Quindi, normalizzando la correlazione con quel numero dovrebbe dare il valore che tu (e io) volevamo. Il prodotto medio per i pixel che non sono mascherati in entrambe le immagini.

 Image imCorr = referenceImage.MatchTemplate(templateImage, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR); Image imCorrMask = referenceImageMask.MatchTemplate(templateMask, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR); _imCorr = _imCorr.Mul(_imCorrMask.Pow(-1)); 

AGGIORNAMENTO: in realtà, questa soluzione non funziona. Poiché l’implementazione della correlazione incrociata in opencv utilizza la DFT ci saranno problemi numerici e non è ansible utilizzare la seconda crosscorrelation per correggere la prima.