Trovare regioni / motivi simmetrici nell'immagine


14

Ho una serie di immagini che rappresentano la curvatura media di una superficie posteriore umana.

Quello che voglio fare è "scansionare" l'immagine per punti che hanno "controparti" simili e riflesse in qualche altra parte dell'immagine (molto probabilmente simmetrica rispetto alla linea mediana, ma non necessariamente poiché potrebbero esserci delle deformità). Alcune tecniche di cucitura di immagini lo usano per "rilevare automaticamente" punti simili tra le immagini, ma voglio rilevarli per entrambi i lati della stessa immagine.

L'obiettivo finale è quello di trovare una linea longitudinale continua, molto probabilmente curva, che divide in modo adattivo la schiena in "metà" simmetriche.

Un'immagine di esempio è posizionata sotto. Si noti che non tutte le regioni sono simmetriche (in particolare, appena sopra il centro dell'immagine, la "striscia" rossa verticale devia a destra). Quella regione dovrebbe ricevere un punteggio negativo, o altro, ma poi la simmetria locale sarebbe definita da punti simmetrici posti più lontano. In ogni caso, dovrò adattare qualsiasi algoritmo al mio dominio di applicazione, ma quello che sto cercando è una strategia di correlazione / convoluzione / pattern-matching, penso che ci sia già qualcosa intorno, penso.

(EDIT: ci sono più immagini qui sotto e qualche spiegazione in più)

inserisci qui la descrizione dell'immagine

MODIFICA: come richiesto, includerò immagini più tipiche, sia ben educate che problematiche. Ma invece delle immagini colormapped, sono in scala di grigi, quindi il colore è direttamente correlato alla grandezza dei dati, che non è accaduto con l'immagine colorata (fornita solo per la comunicazione). Anche se le immagini grigie sembrano prive di contrasto rispetto a quelle colorate, le sfumature dei dati sono presenti e possono essere evidenziate con un certo contrasto adattivo se lo si desidera.


1) Immagine di un soggetto molto simmetrico:

inserisci qui la descrizione dell'immagine


2) Immagine dello stesso soggetto in un momento diverso. Sebbene ci siano più "caratteristiche" (più gradienti), non "sembra" così simmetrico come prima:

inserisci qui la descrizione dell'immagine


3) Un soggetto giovane e sottile, con convessità (sporgenze ossee, indicate da regioni più chiare) sulla linea mediana anziché sulla linea mediana concava più comune:

inserisci qui la descrizione dell'immagine


4) Un giovane con deviazione spinale confermata dai raggi X (notare le asimmetrie):

inserisci qui la descrizione dell'immagine


5) Il tipico soggetto "inclinato" (sebbene per lo più simmetrico attorno alla linea mediana curva, e come tale non "deformato"):

inserisci qui la descrizione dell'immagine


Qualsiasi aiuto è molto gradito!


Perché non usare semplicemente la spina dorsale come divisore?
Jim Clay,

@JimClay: sospetto che la colonna vertebrale sia la parte misurata, rispetto all'asse di simmetria reale del resto dell'immagine
endolith,

"Alcune tecniche di cucitura di immagini lo usano per" rilevare automaticamente "punti simili tra le immagini" Crea una copia capovolta dell'immagine e poi usa una di quelle. :)
endolith il

Non potresti semplicemente rispecchiare l'immagine lungo l'asse Y e utilizzare un algoritmo di registrazione? Perché ci sono già molte ricerche sugli algoritmi di registrazione flessibili / non parametrici su cui puoi basarti.
Niki Estner,

JimClay, la spina dorsale è ciò che voglio trovare, non so dove sia; Endolith, la mia domanda riguarda le persone che mi dicono i nomi di alcuni di quegli algoritmi, che non ho ancora trovato. E Nikie, questo è il punto, ma non CONOSCO nessuno di quegli algoritmi, ecco perché sto ponendo la domanda in primo luogo: o)
heltonbiker,

Risposte:


9

Come ho detto nei commenti, la registrazione di immagini mediche è un argomento con molte ricerche disponibili e non sono un esperto. Da quello che ho letto, l'idea di base comunemente usata è quella di definire una mappatura tra due immagini (nel tuo caso un'immagine e la sua immagine speculare), quindi definire i termini energetici per uniformità e somiglianza dell'immagine se viene applicata la mappatura, e infine ottimizzare questa mappatura usando tecniche di ottimizzazione standard (o talvolta specifiche dell'applicazione).

Ho dimostrato insieme un rapido algoritmo in Mathematica per dimostrarlo. Questo non è un algoritmo che dovresti usare in un'applicazione medica, solo una dimostrazione delle idee di base.

Innanzitutto, carico la tua immagine, la specchio e divido queste immagini in piccoli blocchi:

src = ColorConvert[Import["http://i.stack.imgur.com/jf709.jpg"], 
   "Grayscale"];
mirror = ImageReflect[src, Left -> Right];
blockSize = 30;
partsS = ImagePartition[src, {blockSize, blockSize}];
partsM = ImagePartition[mirror, {blockSize, blockSize}];
GraphicsGrid[partsS]

Grafica Mathematica

Normalmente, faremmo una registrazione rigida approssimativa (usando ad esempio punti chiave o momenti dell'immagine), ma la tua immagine è quasi centrata, quindi la salterò.

Se osserviamo un blocco ed è la sua controparte speculare:

{partsS[[6, 10]], partsM[[6, 10]]}

Grafica Mathematica

Possiamo vedere che sono simili, ma spostati. La quantità e la direzione del turno è ciò che stiamo cercando di scoprire.

Per quantificare la somiglianza della partita, posso usare la distanza euclidea quadrata:

ListPlot3D[
  ImageData[
   ImageCorrelate[partsM[[6, 10]], partsS[[6, 10]], 
    SquaredEuclideanDistance]]]

Grafica Mathematica

purtroppo, usando questi dati è l'ottimizzazione direttamente più difficile di quanto pensassi, quindi ho usato invece un'approssimazione del 2 ° ordine:

fitTerms = {1, x, x^2, y, y^2, x*y};

fit = Fit[
   Flatten[MapIndexed[{#2[[1]] - blockSize/2, #2[[2]] - 
        blockSize/2, #1} &, 
     ImageData[
      ImageCorrelate[partsM[[6, 10]], partsS[[6, 10]], 
       SquaredEuclideanDistance]], {2}], 1], fitTerms, {x, y}];

Plot3D[fit, {x, -25, 25}, {y, -25, 25}]

Grafica Mathematica

La funzione non è la stessa della funzione di correlazione effettiva, ma è abbastanza vicina per un primo passo. Calcoliamo questo per ogni coppia di blocchi:

distancesFit = MapThread[
   Function[{part, template},
    Fit[Flatten[
      MapIndexed[{#2[[2]] - blockSize/2, #2[[1]] - blockSize/2, #1} &,
        ImageData[
        ImageCorrelate[part, template, 
         SquaredEuclideanDistance]], {2}], 1], 
     fitTerms, {x, y}]], {partsM, partsS}, 2];

Questo ci dà il nostro primo termine energetico per l'ottimizzazione:

variablesX = Array[dx, Dimensions[partsS]];
variablesY = Array[dy, Dimensions[partsS]];

matchEnergyFit = 
  Total[MapThread[#1 /. {x -> #2, y -> #3} &, {distancesFit, 
     variablesX, variablesY}, 2], 3];

variablesX/Ycontiene gli offset per ciascun blocco e matchEnergyFitapprossima la differenza euclidea quadrata tra l'immagine originale e l'immagine speculare con gli offset applicati.

L'ottimizzazione di questa sola energia darebbe scarsi risultati (se convergesse del tutto). Vogliamo anche che gli offset siano uniformi, in cui la somiglianza del blocco non dice nulla sull'offset (ad esempio lungo una linea retta o sullo sfondo bianco).

Quindi impostiamo un secondo termine energetico per fluidità:

smoothnessEnergy = Total[Flatten[
    {
     Table[
      variablesX[[i, j - 1]] - 2 variablesX[[i, j]] + 
       variablesX[[i, j + 1]], {i, 1, Length[partsS]}, {j, 2, 
       Length[partsS[[1]]] - 1}],
     Table[
      variablesX[[i - 1, j]] - 2 variablesX[[i, j]] + 
       variablesX[[i + 1, j]], {i, 2, Length[partsS] - 1}, {j, 1, 
       Length[partsS[[1]]]}],
     Table[
      variablesY[[i, j - 1]] - 2 variablesY[[i, j]] + 
       variablesY[[i, j + 1]], {i, 1, Length[partsS]}, {j, 2, 
       Length[partsS[[1]]] - 1}],
     Table[
      variablesY[[i - 1, j]] - 2 variablesY[[i, j]] + 
       variablesY[[i + 1, j]], {i, 2, Length[partsS] - 1}, {j, 1, 
       Length[partsS[[1]]]}]
     }^2]];

Fortunatamente, l'ottimizzazione vincolata è integrata in Mathematica:

allVariables = Flatten[{variablesX, variablesY}];
constraints = -blockSize/3. < # < blockSize/3. & /@ allVariables;
initialValues = {#, 0} & /@ allVariables;
solution = 
  FindMinimum[{matchEnergyFit + 0.1 smoothnessEnergy, constraints}, 
   initialValues];

Diamo un'occhiata al risultato:

grid = Table[{(j - 0.5)*blockSize - dx[i, j], (i - 0.5)*blockSize - 
      dy[i, j]}, {i, Length[partsS]}, {j, Length[partsS[[1]]]}] /. 
   solution[[2]];
Show[src, Graphics[
  {Red,
   Line /@ grid,
   Line /@ Transpose[grid]
   }]]

Grafica Mathematica

Il 0.1fattore precedente smoothnessEnergyè il peso relativo che l'energia di levigatezza ottiene in relazione al termine energetico corrispondente all'immagine. Questi sono risultati per pesi diversi:

Grafica Mathematica

Possibili miglioramenti:

  • Come ho detto, esegui prima una registrazione rigida. Con uno sfondo bianco, la semplice registrazione basata sui momenti dell'immagine dovrebbe funzionare correttamente.
  • Questo è solo un passo. Puoi utilizzare gli offset che hai trovato in un passaggio e migliorarli in un secondo passaggio, magari con una finestra di ricerca più piccola o blocchi di dimensioni inferiori
  • Ho letto articoli in cui lo fanno senza blocchi, ma ottimizzano un offset per pixel.
  • Prova diverse funzioni di scorrevolezza

rispondi troppo a lungo per leggere solo per divertimento, ma l'immagine finale è piuttosto indicativa: sembra incredibile: D
penelope

Questa risposta è stata molto illuminante. Avrò bisogno di un po 'di tempo per ingoiarlo, ma molto probabilmente la tecnica di registrazione non rigida è ciò che dovrò usare. Fortunatamente hai fornito alcuni dettagli concettuali, quindi nel peggiore dei casi posso capire un approccio simile. Nel frattempo, aggiornerò la domanda con più immagini. Grazie per ora!
heltonbiker,

4

Domanda interessante. Innanzitutto, forse stai cercando approcci basati sul rilevatore di punti chiave di interesse e sulla corrispondenza. Ciò includerebbe SIFT (Trasforma invariante di scala), SURF, ORB, ecc ... o anche un approccio più semplice basato esclusivamente sull'operatore Harris (csce.uark.edu/~jgauch/library/Features/Harris.1988.pdf ). Dal tuo post non è chiaro cosa hai provato, quindi mi dispiace se sono ingenuo qui.

Detto questo, consentitemi di adottare un approccio più semplice con Mathematical Morphology (MM) solo per divertimento :) Le immagini per la visualizzazione di tutti i passaggi sono alla fine.

Ho preso la tua immagine di esempio e l'ho convertita nello spazio colore L a b * usando ImageMagick e ho usato solo la banda L *:

convert x.jpg -colorspace Lab -separate %d.png

0.png corrisponde alla banda L *. Ora, sono sicuro che hai i dati reali dell'immagine, ma ho a che fare con artefatti di compressione jpg e cosa no. Per gestire parzialmente questo problema, ho eseguito un'apertura morfologica seguita da una chiusura morfologica con un disco piatto di raggio 5. Questo è un modo di base per ridurre il rumore con MM, e dato il raggio del disco non viene modificata gran parte dell'immagine. Successivamente la mia idea si basava su questa singola immagine, che ha grandi probabilità di fallire in altri casi. La tua regione di interesse si distingue visivamente per essere più scura ("più calda" nella tua immagine a colori), quindi ho supposto che un binarizer basato su statisticamente potesse funzionare bene. Ho usato l'approccio di Otsu, che è automatico.

A questo punto, è possibile visualizzare chiaramente la regione centrale di interesse. Il problema è che, nel mio approccio, volevo che fosse un componente chiuso ma non lo è. Comincio scartando ogni componente collegato che è più piccolo di quello più grande (senza contare lo sfondo come uno di essi). Ciò ha maggiori possibilità di funzionare in altri casi se il risultato della binarizzazione fosse buono. Nell'immagine di esempio, c'è un componente collegato allo sfondo, quindi non viene scartato ma non causa problemi.

Se mi stai ancora seguendo, dobbiamo ancora trovare l'attuale presunta regione centrale di interesse. Ecco la mia opinione a riguardo. Non importa quanto sia curva la persona (in realtà posso vedere alcuni casi problematici), la regione assomiglia a una linea verticale. A tal fine, semplifico l'immagine corrente eseguendo un'apertura morfologica con una linea verticale di lunghezza 100. Questa lunghezza è puramente arbitraria, se non si hanno problemi di ridimensionamento, questo non è un valore difficile da determinare. Ora eliminiamo nuovamente i componenti, ma sono stato un po 'più attento in questo passaggio. Ho usato l'apertura per area con il complemento dell'immagine per scartare ciò che consideravo piccole regioni, questo poteva essere fatto in modo più controllato eseguendo qualcosa sotto forma di analisi granulometriche (anche da MM).

Abbiamo circa tre pezzi ora: la parte sinistra dell'immagine, la parte centrale e la parte destra dell'immagine. La parte centrale dovrebbe essere la componente più piccola delle tre, quindi è banalmente ottenuta.

Ecco il risultato finale, l'immagine in basso a destra è solo l'immagine sovrapposta alla sua sinistra con quella originale. Le singole figure non sono tutte allineate, scusate la fretta.

http://i.imgur.com/XRhYv.png


Grazie mille per il tuo gentile interesse, ma il tuo approccio dovrebbe considerare alcune proprietà dei miei dati (non un reclamo, solo un dettaglio): 1) I dati effettivi sono una matrice 2D di float, colormappati con un divergente rosso-giallo- mappa dei colori verde nel matplotlib di Python. Non penso che lavorare con i dati di colore sia concettualmente corretto, le immagini sono mostrate solo a scopo di comunicazione; 2) I dati effettivi si riferiscono alla curvatura della superficie (convessa vs. concava), con le parti rosse che sono concava e quelle verdi che sono convesse. L'asse simmetrico non cade necessariamente in una regione concava.
heltonbiker,

Presto aggiungerò altre immagini (e sostituirò questa) con quelle in scala di grigi, in modo che le immagini stesse possano essere utilizzate per i test, eliminando il pericolo di distorsione della gamma dinamica dovuta al colore.
heltonbiker,

I dati non sono ancora disponibili, sfortunatamente. Le immagini in scala di grigio sono al massimo un'approssimazione.
mmgp,

Credo che l'approssimazione molto probabilmente sia sufficiente, ma non mi dispiace fornire i dati effettivi. Posso pubblicare alcuni link pubblici per il download di DropBox, ma non so in quale formato di file.
heltonbiker,
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.