Finden von symmetrischen Regionen / Mustern im Bild

14

Ich habe eine Reihe von Bildern, die die mittlere Krümmung einer menschlichen Rückenfläche darstellen.

Was ich tun möchte, ist, das Bild nach Punkten zu "scannen", die ähnliche, reflektierte "Gegenstücke" in einem anderen Teil des Bildes haben (höchstwahrscheinlich symmetrisch zur Mittellinie, aber nicht unbedingt, da es Deformitäten geben könnte). Einige Bildstichtechniken verwenden dies, um ähnliche Punkte zwischen Bildern automatisch zu erkennen, aber ich möchte sie für beide Seiten desselben Bildes erkennen.

Das ultimative Ziel ist es, eine kontinuierliche, höchstwahrscheinlich gekrümmte Längslinie zu finden, die den Rücken adaptiv in symmetrische "Hälften" unterteilt.

Ein Beispielbild ist unten platziert. Beachten Sie, dass nicht alle Bereiche symmetrisch sind (insbesondere weicht der rote vertikale "Streifen" direkt über der Bildmitte nach rechts ab). Diese Region sollte eine schlechte Bewertung erhalten, oder was auch immer, aber dann würde die lokale Symmetrie aus weiter entfernten symmetrischen Punkten definiert. In jedem Fall muss ich jeden Algorithmus an meine Anwendungsdomäne anpassen, aber ich bin auf der Suche nach einer Korrelations- / Faltungs- / Mustervergleichsstrategie. Ich denke, es muss bereits etwas in der Nähe sein.

(BEARBEITEN: Es gibt mehr Bilder unten und einige weitere Erklärungen)

Bildbeschreibung hier eingeben

BEARBEITEN: wie gewünscht, werde ich mehr typische Bilder einfügen, entweder gut erzogen oder problematisch. Anstelle von farbabgebildeten Bildern handelt es sich jedoch um Graustufenbilder, sodass die Farbe in direktem Zusammenhang mit der Datengröße steht, was bei farbigen Bildern nicht der Fall war (nur zur Kommunikation vorgesehen). Obwohl die grauen Bilder im Vergleich zu den farbigen scheinbar keinen Kontrast aufweisen, sind die Datengradienten vorhanden und können auf Wunsch mit einem adaptiven Kontrast versehen werden.


1) Bild eines sehr symmetrischen Motivs:

Bildbeschreibung hier eingeben


2) Bild des gleichen Motivs zu einem anderen Zeitpunkt. Obwohl es mehr "Features" (mehr Farbverläufe) gibt, "fühlt" es sich nicht so symmetrisch an wie zuvor:

Bildbeschreibung hier eingeben


3) Ein dünnes junges Motiv mit Konvexitäten (knöchernen Vorsprüngen, bezeichnet durch hellere Regionen) in der Mittellinie anstelle der häufigeren konkaven Mittellinie:

Bildbeschreibung hier eingeben


4) Ein Jugendlicher mit röntgenologisch bestätigter Wirbelsäulenabweichung (Asymmetrien beachten):

Bildbeschreibung hier eingeben


5) Das typische "gekippte" Objekt (obwohl es meistens symmetrisch um die gekrümmte Mittellinie liegt und als solches nicht richtig "deformiert" ist):

Bildbeschreibung hier eingeben


Jede Hilfe ist herzlich willkommen!

Heltonbiker
quelle
Warum nicht einfach den Rücken als Trennwand benutzen?
Jim Clay
@JimClay: Ich nehme an der Wirbelsäule der Teil ist , die gemessen wird , relativ zu der tatsächlichen Symmetrieachse des Restes des Bild
Endolithe
"Einige Techniken zum Zusammenfügen von Bildern verwenden diese Option, um ähnliche Punkte zwischen Bildern automatisch zu erkennen." Erstellen Sie eine gespiegelte Kopie des Bildes und verwenden Sie dann eine davon. :)
Endolithe
Könnten Sie nicht einfach das Bild entlang der Y-Achse spiegeln und einen Registrierungsalgorithmus verwenden? Weil es bereits viele Untersuchungen zu flexiblen / nichtparametrischen Registrierungsalgorithmen gibt, auf denen Sie aufbauen können.
Niki Estner
JimClay, die Wirbelsäule ist das, was ich finden möchte. Ich weiß nicht, wo sie ist. Endolith, meine Frage betrifft Leute, die mir die Namen einiger dieser Algorithmen nennen, die ich noch nicht gefunden habe. Und Nikie, das ist der springende Punkt, aber ich kenne keinen dieser Algorithmen, deshalb stelle ich die Frage an erster Stelle: o)
heltonbiker

Antworten:

9

Wie ich in den Kommentaren gesagt habe, ist die Registrierung von medizinischen Bildern ein Thema, zu dem es viele Nachforschungen gibt, und ich bin kein Experte. Nach dem, was ich gelesen habe, besteht die häufig verwendete Grundidee darin, eine Zuordnung zwischen zwei Bildern (in Ihrem Fall ein Bild und sein Spiegelbild) zu definieren, dann Energiebegriffe für die Glätte und für die Bildähnlichkeit zu definieren, wenn die Zuordnung angewendet wird, und schließlich Optimieren Sie dieses Mapping mithilfe standardmäßiger (oder manchmal anwendungsspezifischer) Optimierungstechniken.

Ich habe in Mathematica einen schnellen Algorithmus gehackt, um dies zu demonstrieren. Dies ist kein Algorithmus, den Sie in einer medizinischen Anwendung verwenden sollten, sondern nur eine Demonstration der Grundideen.

Zuerst lade ich dein Bild, spiegele es und teile diese Bilder in kleine Blöcke auf:

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]

Mathematica-Grafiken

Normalerweise würden wir eine ungefähre starre Registrierung durchführen (z. B. unter Verwendung von Schlüsselpunkten oder Bildmomenten), aber Ihr Bild ist fast zentriert, sodass ich dies überspringe.

Wenn wir uns einen Block und sein spiegelbildliches Gegenstück ansehen:

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

Mathematica-Grafiken

Wir können sehen, dass sie ähnlich, aber verschoben sind. Das Ausmaß und die Richtung der Verschiebung versuchen wir herauszufinden.

Um die Übereinstimmungsähnlichkeit zu quantifizieren, kann ich den quadratischen euklidischen Abstand verwenden:

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

Mathematica-Grafiken

Leider war die direkte Optimierung unter Verwendung dieser Daten schwieriger als ich dachte, daher habe ich stattdessen eine Approximation 2. Ordnung verwendet:

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}]

Mathematica-Grafiken

Die Funktion ist nicht mit der eigentlichen Korrelationsfunktion identisch, reicht jedoch für einen ersten Schritt aus. Berechnen wir dies für jedes Blockpaar:

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];

Dies gibt uns unseren ersten Energiebegriff für die Optimierung:

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

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

variablesX/Yenthält die Offsets für jeden Block und matchEnergyFitapproximiert die quadratische euklidische Differenz zwischen dem Originalbild und dem gespiegelten Bild, wobei die Offsets angewendet werden.

Die Optimierung dieser Energie allein würde schlechte Ergebnisse liefern (wenn sie überhaupt konvergiert). Wir möchten auch, dass die Offsets glatt sind, wobei die Blockähnlichkeit nichts über den Offset aussagt (z. B. entlang einer geraden Linie oder im weißen Hintergrund).

Also haben wir einen zweiten Energiebegriff für die Glätte aufgestellt:

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]];

Glücklicherweise ist in Mathematica eine eingeschränkte Optimierung integriert:

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

Schauen wir uns das Ergebnis an:

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]
   }]]

Mathematica-Grafiken

Der 0.1vorhergehende Faktor smoothnessEnergyist das relative Gewicht, das die Glättungsenergie in Bezug auf den Bildanpassungsenergieterm erhält. Dies sind Ergebnisse für verschiedene Gewichte:

Mathematica-Grafiken

Mögliche Verbesserungen:

  • Führen Sie, wie gesagt, zuerst eine starre Registrierung durch. Bei einem weißen Hintergrund sollte eine einfache Registrierung auf der Basis von Bildmomenten problemlos funktionieren.
  • Dies ist nur ein Schritt. Sie können die gefundenen Offsets in einem Schritt verwenden und in einem zweiten Schritt verbessern, z. B. mit einem kleineren Suchfenster oder kleineren Blockgrößen
  • Ich habe Artikel gelesen, in denen sie dies ohne Blöcke tun, aber einen Versatz pro Pixel optimieren.
  • Probieren Sie verschiedene Glättungsfunktionen aus
Niki Estner
quelle
Antwort zu lang, um nur zum Spaß zu lesen, aber das endgültige Bild ist ziemlich bezeichnend: es sieht toll aus: D
Penelope
Diese Antwort war sehr aufschlussreich. Ich brauche etwas Zeit, um es zu schlucken, aber höchstwahrscheinlich muss ich die nicht starre Registrierungstechnik anwenden. Glücklicherweise haben Sie einige konzeptionelle Details angegeben, sodass ich im schlimmsten Fall einen ähnlichen Ansatz finden kann. In der Zwischenzeit werde ich die Frage mit weiteren Bildern aktualisieren. Danke erstmal!
Heltonbiker
4

Interessante Frage. Erstens, vielleicht suchen Sie nach Ansätzen, die auf dem Erkennen und Anpassen von Schlüsselpunkten basieren. Dies umfasst SIFT (Skaleninvariante Feature-Transformation), SURF, ORB usw. oder sogar einen einfacheren Ansatz, der ausschließlich auf dem Harris-Operator basiert (csce.uark.edu/~jgauch/library/Features/Harris.1988.pdf) ). Aus Ihrem Beitrag geht nicht hervor, was Sie versucht haben. Es tut mir leid, wenn ich hier naiv bin.

Gestatten Sie mir zum Spaß einen einfacheren Ansatz mit Mathematical Morphology (MM) :) Bilder zur Visualisierung aller Schritte sind am Ende.

Ich habe Ihr Beispielbild genommen und es mit ImageMagick in den L a b * -Farbraum konvertiert und nur das L * -Band verwendet:

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

0.png entspricht dem L * -Band. Jetzt bin ich sicher, dass Sie die tatsächlichen Bilddaten haben, aber ich beschäftige mich mit JPG-Komprimierungsartefakten und was nicht. Um dieses Problem teilweise zu lösen, führte ich eine morphologische Öffnung durch, gefolgt von einer morphologischen Schließung mit einer flachen Scheibe mit Radius 5. Dies ist eine grundlegende Methode zur Reduzierung des Rauschens mit MM, und angesichts des Scheibenradius wird nicht viel am Bild geändert. Als nächstes basierte meine Idee auf diesem einzelnen Bild, das in anderen Fällen mit großer Wahrscheinlichkeit versagt. Ihre Region von Interesse zeichnet sich optisch dadurch aus, dass sie dunkler ("heißer" in Ihrem Farbbild) ist. Ich nahm also an, dass ein statistisch basierter Binärbildschirm eine gute Leistung bringen könnte. Ich habe den automatischen Ansatz von Otsu verwendet.

An dieser Stelle ist es möglich, den zentralen interessierenden Bereich klar zu visualisieren. Das Problem ist, dass ich in meinem Ansatz wollte, dass es eine geschlossene Komponente ist, aber nicht. Ich beginne damit, jede verbundene Komponente zu verwerfen, die kleiner als die größte ist (Hintergrund zählt nicht dazu). Dies hat eine größere Chance, in anderen Fällen zu funktionieren, wenn das Binärergebnis gut war. In Ihrem Beispielbild ist eine Komponente mit dem Hintergrund verbunden, sodass sie nicht verworfen wird, aber keine Probleme verursacht.

Wenn Sie mir noch folgen, müssen wir noch die eigentliche vermeintliche zentrale Region von Interesse finden. Hier ist meine Meinung dazu. Egal wie gekrümmt die Person ist (tatsächlich kann ich bestimmte Problemfälle sehen), die Region ähnelt einer vertikalen Linie. Zu diesem Zweck vereinfache ich das aktuelle Bild, indem ich eine morphologische Öffnung mit einer vertikalen Linie der Länge 100 durchführe. Diese Länge ist rein willkürlich. Wenn Sie keine Skalierungsprobleme haben, ist dies kein schwer zu bestimmender Wert. Jetzt verwerfen wir wieder Komponenten, aber ich war bei diesem Schritt etwas vorsichtiger. Ich habe das Öffnen nach Bereichen mit dem Bildkomplement verwendet, um die von mir als klein geltenden Bereiche zu verwerfen. Dies könnte auf kontrollierte Weise geschehen, indem etwas in Form einer Granulometrieanalyse (auch von MM) durchgeführt wird.

Wir haben jetzt ungefähr drei Teile: den linken Teil des Bildes, den mittleren Teil und den rechten Teil des Bildes. Es wird erwartet, dass der zentrale Teil die kleinere Komponente der drei ist, so dass er trivial erhalten wird.

Hier ist das Endergebnis: Das Bild unten rechts ist nur das Bild, das mit dem Originalbild links überlagert ist. Die einzelnen Figuren stimmen nicht alle überein, sorry für die Eile.

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

mmgp
quelle
Vielen Dank für Ihr freundliches Interesse, aber Ihr Ansatz sollte bestimmte Eigenschaften meiner Daten berücksichtigen (keine Beschwerde, nur eine Detaillierung): 1) Die tatsächlichen Daten sind ein 2D-Array von Floats, farbig mit einem divergierenden Rot-Gelb-Muster. grüne Farbkarte in Pythons Matplotlib. Ich denke nicht, dass die Arbeit mit den Farbdaten konzeptionell korrekt wäre. Die Bilder werden nur zu Kommunikationszwecken gezeigt. 2) Die tatsächlichen Daten beziehen sich auf die Oberflächenkrümmung (konvex vs. konkav), wobei rote Teile konkav und grüne konvex sind. Die symmetrische Achse fällt nicht unbedingt in einen konkaven Bereich.
Heltonbiker
Ich werde sehr bald weitere Bilder hinzufügen (und diese durch Graustufenbilder ersetzen), damit die Bilder selbst zu Testzwecken verwendet werden können, um die Gefahr einer Verzerrung des Dynamikbereichs aufgrund von Farben auszuschließen.
Heltonbiker
Die Daten sind leider noch nicht verfügbar. Die Graustufenbilder sind bestenfalls eine Annäherung.
MMGP
Ich glaube, die Annäherung ist höchstwahrscheinlich genug, aber es macht mir nichts aus, die tatsächlichen Daten bereitzustellen. Ich kann einige öffentliche DropBox-Download-Links posten, weiß aber nicht, in welchem ​​Dateiformat.
Heltonbiker