Problema di segmentazione delle immagini di diversi materiali


15

Salve CV / Pattern Recognition Community,

Ho un problema serio riguardo alla segmentazione di un'immagine. Lo scenario è un'atmosfera all'interno di una fornace che mi fa impazzire la testa. E ho bisogno di rilevare i contorni degli oggetti di diversi materiali (vetro, ceramica, Al, Ir, ..) in un breve periodo di tempo (<10 secondi) e non solo per un caso speciale. Ho anche bisogno del contorno in una fila sequenziale di pixel per il codice. Pertanto è necessario anche un codice catena o il cosiddetto seguito di bordo / contorno, quindi i fori aperti non sono buoni. Sullo sfondo ci sono rumori non lineari, approssimativamente di polvere, particelle o qualcosa del genere, che appaiono di volta in volta.

Suggerimenti Matlab o OpenCV sono benvenuti.

Per renderlo più chiaro, ho pubblicato un'altra immagine del mio obiettivo e un oggetto semitrasparente, che deve anche essere rilevato. Ulteriori esempi di cui è necessario essere consapevoli. Esempio 1 example2 Example3 Esempio4

Come puoi vedere nell'immagine n. 1, ci sono particelle nella parte destra dell'immagine e vicino al contorno esterno della stella, che è l'oggetto. Anche il contrasto complessivo non è molto buono. L'oggetto stesso si trova su un sottosuolo, che non è rilevante per il rilevamento del contorno. L'immagine n. 2 mostra un oggetto semitrasparente, che è anche possibile.

Voglio trovare il contorno / perimetro di quell'oggetto, come nella schermata successiva (linea rossa). I due rettangoli (gialli) indicano il punto iniziale (a sinistra) e il punto finale (a destra). La linea blu è ignorabile. example2

All'inizio ho pensato di poter risolvere il problema di quell'atmosfera sporca con solo filtri. Ma dopo un'onorevole quantità di tempo investito, mi sono appena reso conto che devo eliminare o ridurre significativamente i rumori per aumentare il contrasto tra primo piano e sfondo. Avevo provato molti metodi, come l'equalizzazione dell'istogramma, l'equalizzazione adattativa Otsu, i filtri lineari (ad es. Gauss), i filtri non lineari (mediana, diffusione), i contorni attivi, i mezzi k, i fuzzy-c e anche i Canny per puro Edge Detection in combinazione con operatori morfologici.

  • Canny: le particelle e l'atmosfera stanno causando buchi, ma ho bisogno di un contorno completo dell'oggetto. Ancora con la chiusura, la dilatazione degli operatori morfologici non è abbastanza bene. Canny ha ancora i migliori risultati di tutti i metodi che ho studiato a causa dell'isteresi.
  • Contorni attivi: funzionano anche su bordi / gradienti, agiscono completamente in modo folle dopo l'inizializzazione all'interno dell'oggetto, che forse è causata dalla mappa dei bordi risultante nell'oggetto 'aperto'. Per quanto ne so, il contorno deve essere chiuso. Provato con diversi derivati ​​(GVF / VFC / Classic Snake).
  • Mezzi k: i risultati includono l'atmosfera della fornace, a causa dello sfondo nebbioso. Lo stesso per fuzzy-c-significa. Ho scelto due cluster, a causa della separazione dell'oggetto dallo sfondo. Più cluster portano a risultati più deboli.
  • Istogramma / Otsu: a causa dell'intensità grigia molto vicina (imho!), Sta fondendo l'oggetto con lo sfondo. Provato con metodi locali e globali.
  • Filtri: Soprattutto GLPF o altri LPF stanno imbrattando i bordi, il che non è così buono e non riduce nemmeno l'atmosfera nebbiosa.
  • I filtri non lineari preservano i bordi. La maggior parte impiega troppo tempo per calcolare le immagini di grandi dimensioni. Ho preso un filtro bilaterale veloce per ora. I risultati vedi sotto.

Pertanto, non un singolo metodo è abbastanza buono per le fasi di post-elaborazione, poiché i risultati ottenuti del segmento di oggetti sono in scarsa concorrenza con un algoritmo esistente. L'algoritmo esistente è molto locale e quindi funziona per questo scenario molto speciale.

Quindi ti sto chiedendo se ho perso qualcosa completamente ... Non ho più idea di come elaborare e come dovrei ottenere buoni risultati di contorno, senza buchi o buchi .. È possibile senza apportare molte modifiche al CCD e ambiente fisico? Grazie in anticipo!

Last Approach finora (dopo una lunga notte di esperimenti con MO):

  • Filtro bilaterale (preservando i bordi, ma levigando le aree omogenee)
  • Canny (Sigma = 2, Soglia = [0,04 0,08])
  • Morfologica Operations (MO): bwareopen, closing, remove&bridge
  • bwlabelper selezionare solo il perimetro del contorno, che rimuove i rumori indesiderati. non sono ancora presenti schermate aggiornate, ma funziona per la stella. il vetro ha un contorno interno che è collegato al contorno esterno, che può anche essere visto nella schermata qui sotto.

Quindi temo di aver bisogno di un algoritmo speciale per l'attraversamento del contorno esterno. Sarà una ricerca del vicinato in senso orario / antiorario. Questo passaggio in senso orario / antiorario può cambiare, se c'è un punto d'angolo. se c'è un divario, aumentare il raggio e guardare di nuovo. se ci sono due o più possibili punti seguenti, prendi quello che ha ottenuto la stessa direzione del precedente. Pensi che il profilo che segue l'algoritmo abbia un senso?

Bordi di vetro Stella


Hai provato la soglia adattativa? Sembra che tu non ne parli. Penso che OTSU dovrebbe funzionare in qualche modo dopo aver rimosso il rumore, ma forse la soglia adattativa è migliore.
Rui Marques,

Ciao Rui, ho provato la soglia adattativa con questa estensione Matlab: soglia adattiva Ecco i risultati per giocare con i parametri della finestra: 1 ° tentativo 2 ° tentativo 3 ° tentativo Come puoi vedere, con l'aumento dei parametri la parte centrale passa dal bianco al nero (cosa è buono, imho) ma anche il resto dello sfondo diventa nero, ciò che è male.
mchlfchr,

3
Hai provato alcune tecniche di base per la riduzione delle immagini? Come sottrarre una correzione del campo piatto per sbarazzarsi di quell'oscuramento in alto a destra ( en.wikipedia.org/wiki/Flat-field_correction ). Inoltre, se le particelle sono statiche, verrebbero immediatamente rimosse. Quindi, è possibile utilizzare qualsiasi metodo di rilevamento dei bordi desiderato ...
PhilMacKay,

Ciao Phil, per quanto mi riguarda e per quanto ne so, c'è una serie di immagini che vengono scattate prima che un oggetto entri nella fornace. Il tipo di calibrazione è quindi qui. Parlerò con il fisico che è responsabile per il CCD e l'ambiente lunedì. Ma grazie per il consiglio, ci proverò!
mchlfchr,

La seconda immagine che hai aggiunto sembra totalmente diversa. Puoi pubblicare tutte le immagini possibili?
Andrey Rubshtein,

Risposte:


2

Puoi provare quanto segue:


Ciao oli, per quanto riguarda i metodi sparsi: potresti essere più specifico di quali metodi di quel codice dovrei usare? Non sono molto approfondito in quella sezione e non ho trovato qualcosa di utile nei documenti riguardanti il ​​de-noise o la sfocatura ... Grazie in anticipo.
mchlfchr,

1
Puoi trovare una versione "più facile da usare", qui: lear.inrialpes.fr/people/mairal/denoise_ICCV09.tar.gz
oli,

mi dispiace lamentarmi un'altra volta ;-) ... hai anche fonti win32? grazie ancora!
mchlfchr,

Temo di non ...
oli,

2

Penso che tu abbia rinunciato troppo presto alle tecniche di soglia. Dai un'occhiata al tuo istogramma, è chiaramente tri-modale: (ho rimosso manualmente le colonne bianche a destra dell'immagine, presumo che non facciano parte dell'immagine, per favore prendi questa immagine prima di eseguire il mio codice)

inserisci qui la descrizione dell'immagine

Dai un'occhiata a tutti i valori nel primo gruppo:

inserisci qui la descrizione dell'immagine

Per trovare le modalità nell'istogramma trimodale, è possibile usare il clustering dei mezzi K con K=3intensità. Il seguente codice Matlab si trova th1=67sul tuo codice. L'idea è di supporre di avere i 3 set e calcolare il centroide ponderato su ciascuno di essi. Quindi, ogni livello di intensità viene assegnato al proprio cluster. Ti fermi quando i centroidi ponderati cessano di muoversi. Ecco il risultato della ricerca di due soglie sulla tua immagine, mostrate nell'istogramma.

inserisci qui la descrizione dell'immagine

function [th1,th2]=SegmentHistTo3()
    im = imread('http://i.stack.imgur.com/U2sc5.png');
    h = imhist(im(:,:,1)); %# Calculate histogram

    th1new = round(256/3); %# Initial thresholds
    th2new = round(256*2/3);
    th1 = 0;
    th2 = 0;

    while (th1~=th1new) || (th2~=th2new) %# While the centroids keep on moving
        th1 = th1new;
        th2 = th2new;

        wa1 = WeightedAverage(h,1,th1);  %# Calculate 3 weighted averages
        wa2 = WeightedAverage(h,th1+1,th2);
        wa3 = WeightedAverage(h,th2,numel(h));

        th1new = round( (wa1+wa2)/2 );  %# The thresholds are middle points between the averages
        th2new = round( (wa2+wa3)/2 );
    end

    figure; hist( double( reshape(im(:,:,1),1,[]) ),256);
    hold on;
    plot( [th1 th1],[0 max(h)],'r','LineWidth',2);
    plot( [th2 th2],[0 max(h)],'r','LineWidth',2);

    figure;imshow( im(:,:,1)<th1);
end

function wa = WeightedAverage(region,th1,th2)    
    regionNonEmpty(th1:th2) = region(th1:th2);
    wa = sum( regionNonEmpty .* (1:numel(regionNonEmpty))) / sum(regionNonEmpty);    
end

Risolvere il problema in seguito è un gioco da ragazzi, basta fare alcune semplici operazioni morfologiche, come l'apertura.


1
Ciao Andrey, ma come dovrei fare una generalizzazione di quella soglia che hai menzionato? Ho avuto diversi casi, non solo quello e ho ancora bisogno di automazione. E l'Otsu Thresholding (funzione in matlab) non mi ha dato buoni risultati. Ulteriori suggerimenti? Cordiali saluti
mchlfchr,

Ciao di nuovo, grazie finora, ma il codice non funziona. Viene visualizzata una schermata vuota. Ho provato con i miei dati originali (bitmap) e il PNG che hai pubblicato sopra. Nel frattempo sto
eseguendo il

@mchlfchr, hai una cassetta degli attrezzi per l'elaborazione delle immagini? In caso contrario, è possibile passare imhistahist
Andrey Rubshtein il

@mchlfchr, si prega di consultare la versione aggiornata
Andrey Rubshtein,

Andrey, se inserisco il file bitmap originale, i risultati sono come ho detto nel mio post di origine. Forse sta succedendo questo riguardo alla risoluzione? L'immagine di origine è 576x768 pixel e scala di grigi (256). Ecco i risultati, se uso la tua funzione con la mia immagine originale: i.imgur.com/UXALJ.png istogramma-figura della tua funzione: i.imgur.com/7RiPP.png Grazie per il tuo aiuto! saluti
mchlfchr,

1

Come suggerito sopra, la soglia può essere molto efficace su questa immagine, che è essenzialmente binaria, tranne per il fatto che una soglia costante non funzionerà a causa dell'illuminazione irregolare. Hai bisogno di una soglia adattativa.

Il mio consiglio sarebbe di fare la ricostruzione di sfondo con un modello semplice (possibilmente planare [3 DOF] o quadradico [6 DOF]), campionando un piccolo numero di valori nelle regioni luminose. La cosa migliore è usare piccoli ROI per eliminare il rumore in media. Quindi correggere l'ombreggiatura sottraendo (o dividendo) i valori di sfondo.

Se l'interazione umana non è un'opzione, è possibile automatizzare la ricerca di aree di sfondo prima Otsu direttamente e considerando ROI uniformi (bassa varianza) ben al di sotto della soglia. Dopo una prima ricostruzione di sfondo, probabilmente puoi migliorare applicando questo processo all'immagine con correzione piatta.

L'intero processo può essere implementato per funzionare ben al di sotto di un secondo.


Ciao Yves, è preferibile un'elaborazione automatizzata. L'aspetto DOF è interessante, ma non sono sicuro del metodo Otsu, perché Otsu stesso non funziona bene. Sto capendo bene che vuoi selezionare aree casuali dell'immagine e quindi soglia dopo il valore medio su tutte le aree selezionate? Cordiali saluti
mchlfchr,

1

Penso che il modo migliore sia usare i contorni attivi. Se non sei a conoscenza di quali contorni attivi dai un'occhiata a questo video su YouTube http://www.youtube.com/watch?v=ijNe7f3QVdA

Fondamentalmente, devi dare una segmentazione di inizializzazione e questo migliorerà la forma. Il mio suggerimento è quello di uno dei metodi discussi in questo post e utilizzare contorni attivi come secondo passo, ad es. come passo di miglioramento.

Ecco un'implementazione di contorni attivi che è possibile utilizzare http://www.mathworks.com/matlabcentral/fileexchange/19567


Benvenuto in dsp.se :) Grazie per il tuo contributo, hai fornito una bella risposta. Se vuoi renderlo ancora migliore, penso che sarebbe interessante fornire risposte ad alcune di queste domande: perché pensi che questo sia l'approccio migliore (ad es. Hai esperienza personale con la tecnica)? Quale degli approcci già suggeriti pensi che funzionerebbe bene in combinazione con il tuo suggerimento? Offri una breve spiegazione della tecnica o, se hai tempo, prova a fornire risultati sperimentali usando la tecnica sulle immagini di esempio fornite. E divertiti su dsp!
penelope,

@mkuse, come potresti aver letto il post iniziale, avevo già provato i contorni attivi, combinati con la riduzione del rumore e le mappe dei bordi. i risultati furono pessimi e ebbe un pessimo tempo di esecuzione per immagini di grandi dimensioni.
mchlfchr,

che ne dici di dare un'occhiata alle tecniche di riduzione del rumore. Puoi trovare un riassunto di quelli qui: lnmiitdip.files.wordpress.com/2011/12/…
mkuse

1
@mkuse, ho già menzionato i meccanismi che hai pubblicato nel tuo file PPT nel mio post iniziale. Ho modificato il mio post iniziale, per rendere più chiaro, che tipo di filtri ho usato.
mchlfchr,

0

Sai chiaramente di cosa ti occupi, ma non hai menzionato l'uso della soglia, in particolare hai provato ad applicare una soglia globale utilizzando Otsu per calcolare il livello giusto, quindi trovare i contorni e selezionare il più grande?

[Modifica per chiarire]

La soglia globale ovviamente non funzionerà a causa del graident visibile sull'immagine.

Ho avuto un gioco veloce con questo e ho scoperto che se rompi l'immagine in 6 pezzi (2 file di 3 colonne di uguali dimensioni), quindi esegui il limite usando Otsu su ognuna e poi rimontaggi, fa un bel lavoro divino nel ripulire il Immagine.

Ci sono ancora alcuni piccoli artefatti nella parte in alto a destra della stella.

Mi viene in mente che, dal momento che l'oggetto ha confini di linea retta, potresti voler considerare una trasformazione di Hough per estrarre questi bordi, intersecarli per localizzare i vertici e utilizzare il risultato come contorno dell'oggetto.


Ciao Dave, ho provato Otsu, ma porta l'effetto che il giusto sfondo superiore si fonde con l'oggetto, il che è assolutamente inaccettabile.
mchlfchr,

Ciao Dave, Hough non è un'opzione, a causa dei requisiti di runtime e per quanto ne so l'HT, richiede molto tempo per immagini di grandi dimensioni.
mchlfchr,

0

I contorni sono sempre linee rette o curve conosciute?

In tal caso, invece di cercare di correggere ogni pixel lungo il bordo, utilizzerei le trasformazioni di Hough per ottenere le equazioni delle linee e quindi ricreare i contorni dalle linee e dalle sezioni


1
Come ho già detto: ho bisogno di approcci in tempo reale vicini. E per quanto ne so l'HT, richiede molto tempo. Un altro aspetto è che non conosco le curve e le linee non sono sempre dritte. Il contorno dipende dal materiale che si trova nella fornace (per ulteriori informazioni, vedere il mio post di origine).
mchlfchr,

Per le linee rette è abbastanza veloce e se sai approssimativamente dove sono le linee (ad esempio da un fotogramma precedente) puoi cercare solo quello spazio dei parametri
Martin Beckett,
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.