Come posso rilevare oggetti distinti quando i loro bordi si toccano?


21

Devo trovare tutti i contorni in un'immagine recuperata dalla fotocamera. Quindi per prima cosa uso il rilevatore di bordi canny per trovare i bordi e poi trovare i contorni. Abbastanza semplice.

Tuttavia, i miei contorni si "fondono". Ad esempio, nell'immagine qui sotto, ho chiaramente 4 oggetti diversi. I bordi si toccano leggermente in alcuni punti, quindi ottengo un contorno grande anziché quattro separati. Ho provato a cambiare soglie, erosione, operazioni di morfologia e cose simili ma i bordi continuano a toccarsi leggermente. Qualcuno ha qualche suggerimento su come ottenere contorni separati in immagini simili a quello qui sotto? (L'immagine qui sotto è ovviamente solo un esempio, le mie immagini reali sono molto più complesse, ma hanno lo stesso problema di base).

inserisci qui la descrizione dell'immagine


La segmentazione del bacino idrografico può funzionare.
sm176357,

Quindi, dovresti anche considerare i casi in cui il contatto è una linea e non solo un punto (toccando ma non si sovrappongono)
Shravya Boggarapu

Risposte:


11

Rilevamento di diversi componenti:

Se stai cercando di rilevare i diversi componenti, probabilmente ci sono altri approcci per farlo oltre a rilevare i contorni. Ecco un esempio in Mathematica. Un'erosione seguita da dilatazione viene utilizzata per colmare il divario nel secondo componente prima del rilevamento (se non lo si fa, non lo rileverà).

img = Binarize@Import["http://i.stack.imgur.com/yqDyu.png"];
Colorize[MorphologicalComponents[Dilation[Erosion[img,1],1]]]

La figura a sinistra in basso, mostra il rilevamento di oggetti imperfetti (senza chiudere lo spazio) e a destra, mostra il rilevamento corretto (eseguendo il codice sopra).

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Rilevamento dei diversi contorni:

Tuttavia, se vuoi davvero separare solo i contorni, ecco un esempio. L'erosione e la dilatazione vengono eseguite come prima per colmare il divario e l'immagine risultante viene eseguita attraverso un rilevatore di bordi Canny. Ho reso esplicite le opzioni predefinite, in modo da poter vedere cosa viene utilizzato.

img2 = EdgeDetect[Dilation[Erosion[img, 1], 1], Method -> "Canny"]

Questo ti darà sia il bordo interno che quello esterno (vedi figura a sinistra in basso), poiché la larghezza dei pixel è maggiore di 1 tutto intorno. Non ho avuto molta fortuna cercando di renderlo più sottile, poiché le prestazioni peggiorano (potrebbe essere diverso per le altre tue immagini). I contorni interni sono quelli desiderati e il contorno esterno è solo il contorno combinato di tutti e 4 i componenti. Ora tutto ciò che dobbiamo fare è eliminare quello più esterno con:

SelectComponents[img2, "EnclosingComponentCount", # > 0 &]

che ti dà solo i contorni interni (vedi in basso a destra). In altre parole, seleziona solo quei contorni racchiusi da almeno un altro contorno, che squalifica automaticamente quello più esterno. Non conosco l'equivalente di questi comandi / operazioni in openCV.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Si noti che le interruzioni apparenti nella figura sono dovute al salvataggio in jpeg in dimensioni inferiori. Non sembra così sul mio schermo.


2

Prova a pre-elaborare le tue immagini con un filtro morfologico come l' erosione . Ciò consentirà di separare i contorni toccanti. Dopo aver rilevato i contorni, è possibile applicare un'operazione di dilatazione per completare i reticoli.


Ci ho provato, ma i risultati non hanno mostrato miglioramenti.

1
Puoi mostrare un'immagine di esempio reale?

2

Non è una risposta alla tua domanda, ma l'analisi del profilo è soggetta a errori. Non puoi farci molto e funziona solo su scenari molto semplici.

Se hai problemi ad usarlo, dovresti cercare un algoritmo completamente diverso. Esistono modi più complessi e più solidi per risolvere le cose, ma dipende da ciò che si desidera ottenere (rilevamento degli oggetti, tracciamento, ecc ...)


Grazie. Il mio programma è utilizzato per il rilevamento delle mani, quindi penso che sarebbe molto simile al rilevamento degli oggetti. Hai dato qualche suggerimento per algoritmi più complessi e robusti? Funzionalità Haar, SURF e algoritmi di apprendimento automatico simili non sono qualcosa che posso fare.

Hai guardato queste risorse? paginas.fe.up.pt/~hgc2011 Sono principalmente database / risultati, ma spero che tu possa trovare dei buoni documenti qui.

0

I contorni non sono necessariamente aperti, considera che hai usato astuto per rilevarli. I problemi con Canny erano già disccused qui . La discussione su canny ti dà l'idea di base che ci sono ancora operazioni come la chiusura e la dilatazione che sono necessarie sopra il canny per valutare i contorni chiusi.

Questo dipende anche dal fatto che cerchiamo contorni o segmentazioni (Canny rispetto a metodi come Graphcuts ). Quindi immagino che la ricerca di una soluzione affidabile dipenda dalla tua applicazione finale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.