Ich habe zwei Bilder, die genau den gleichen Inhalt zeigen: 2D-Gaußsche Flecken. Ich rufe diese beiden 16-Bit Png-Dateien "left.png" und "right.png". Da sie jedoch durch eine etwas andere optische Anordnung erhalten werden, erscheinen die entsprechenden Punkte (physisch die gleichen) an leicht unterschiedlichen Positionen. Das heißt, das Recht ist leicht gestreckt, verzerrt oder nichtlinear. Deshalb möchte ich die Transformation von links nach rechts bekommen.
Also für jedes Pixel auf der linken Seite mit seiner x- und y-Koordinate möchte ich eine Funktion, die mir die Komponenten des Verschiebungsvektors gibt, die auf das entsprechende Pixel auf der rechten Seite zeigen.
In einem früheren Ansatz versuchte ich, die Positionen der entsprechenden Punkte zu erhalten, um die relativen Abstände deltaX und deltaY zu erhalten. Diese Abstände passte ich dann an die Taylor-Erweiterung bis zur zweiten Ordnung von T (x, y) und gab mir die x- und y-Komponente des Verschiebungsvektors für jedes Pixel (x, y) auf der linken Seite und zeigte auf das entsprechende Pixel (x ', y') rechts.
Um ein allgemeineres Ergebnis zu erhalten, möchte ich eine normalisierte Kreuzkorrelation verwenden. Dazu multipliziere ich jeden Pixelwert von links mit einem entsprechenden Pixelwert von rechts und summe über diese Produkte. Die Transformation, nach der ich suche, sollte die Pixel verbinden, die die Summe maximieren. Wenn die Summe maximiert ist, weiß ich, dass ich die entsprechenden Pixel multipliziert habe.
Ich habe wirklich viel damit versucht, aber es hat nicht geklappt. Meine Frage ist, ob jemand von Ihnen eine Idee hat oder etwas Ähnliches getan hat.
%Vor%Bitte lassen Sie mich wissen, wenn ich diese Frage klarer machen kann. Ich muss immer noch überprüfen, wie man Fragen mit Latex stellt.
Vielen Dank für die Eingabe.
[left.png] Ссылка [right.png] Ссылка
Ich fürchte, in den meisten Fällen erscheinen 16-Bit-Bilder nur schwarz (zumindest auf Systemen, die ich benutze) :( aber natürlich sind da Daten drin.
Ich versuche meine Frage zu klären. Ich suche nach einem Vektorfeld mit Verschiebungsvektoren, die von jedem Pixel in left.png auf das entsprechende Pixel in right.png zeigen. Mein Problem ist, dass ich mir über die Einschränkungen, die ich habe, nicht sicher bin.
%Vor%wobei der Vektor r (Komponenten x und y) auf ein Pixel in left.png zeigt und der Vektor r-prime (Komponenten x-prime und y-prime) auf das entsprechende Pixel in right.png zeigt. für jedes r gibt es einen Verschiebungsvektor.
Was ich früher gemacht habe, war, dass ich manuell Komponenten des Vektorfelds d gefunden und auf ein Polynom zweiten Grades gebracht habe:
%Vor%Also passte ich:
%Vor%und
%Vor%Macht das für Sie Sinn? Ist es möglich, alle Delta-x (x, y) und Delta-y (x, y) mit Kreuzkorrelation zu erhalten? Die Kreuzkorrelation sollte maximiert werden, wenn die entsprechenden Pixel durch die Verschiebungsvektoren miteinander verbunden sind, richtig?
Also der Algorithmus, an den ich dachte, ist wie folgt:
Über Deformation: könnte man zuerst eine Verschiebung entlang der x- und y-Richtung machen, um die Kreuzkorrelation zu maximieren, dann in einem zweiten Schritt x- und y-abhängig dehnen oder komprimieren und in einem dritten Schritt quadratisch x- und y deformieren -abhängig und wiederholen Sie dieses Verfahren iterativ? Ich habe wirklich ein Problem, dies mit Integer-Koordinaten zu tun. Meinst du, ich müsste das Bild interpolieren, um eine kontinuierliche Verteilung zu erhalten? Ich muss nochmal darüber nachdenken :( Danke an alle für die Teilnahme:)
OpenCV (und damit die Python-Opencv-Bindung) hat eine StarDetector Klasse, die
Als Alternative können Sie sich die OpenCV-Klasse SIFT ansehen, die steht für Scale Invariant Feature Transformation.
Aktualisieren
In Bezug auf Ihren Kommentar verstehe ich, dass die "richtige" Transformation die Kreuzkorrelation zwischen den Bildern maximiert, aber ich verstehe nicht, wie Sie die Menge der Transformationen auswählen, über die Sie maximieren möchten. Vielleicht, wenn Sie die Koordinaten von drei übereinstimmenden Punkten kennen (entweder durch einige Heuristiken oder indem Sie sie manuell auswählen), und wenn Sie Affinität erwarten, könnten Sie etwas wie cv2.getAffineTransform , um eine gute Anfangstransformation für Ihren Maximierungsprozess zu erhalten. Von dort können Sie kleine zusätzliche Transformationen verwenden, um eine Menge zu maximieren. Aber dieser Ansatz scheint mir etwas neu zu erfinden, auf das SIFT aufpassen könnte.
Um Ihr Testbild tatsächlich zu transformieren, können Sie auch cv2.warpAffine verwenden kann auf Randwerte achten (zB Pad mit 0). Um die Kreuzkorrelation zu berechnen, können Sie scipy.signal verwenden .correlate2d .
Aktualisieren
Ihr letztes Update hat in der Tat einige Punkte für mich geklärt. Aber ich denke, dass ein Vektorfeld von Verschiebungen nicht die natürlichste Sache ist, nach der zu suchen ist, und hier kam auch das Missverständnis. Ich dachte eher an die globale Transformation T, die für jeden beliebigen Punkt (x, y) des linken Bildes gilt (x ', y') = T (x, y) die rechte Seite, aber T hat für jedes Pixel die gleiche analytische Form. Zum Beispiel könnte dies eine Kombination aus Verschiebung, Rotation, Skalierung, vielleicht einer perspektivischen Transformation sein. Ich kann nicht sagen, ob es realistisch ist oder nicht, eine solche Transformation zu finden, das hängt von Ihrem Aufbau ab, aber wenn die Szene auf beiden Seiten physisch gleich ist, würde ich sagen, dass es vernünftig ist, eine affine Transformation zu erwarten. Aus diesem Grund habe ich cv2.getAffineTransform vorgeschlagen. Es ist natürlich trivial, Ihr Verschiebungsvektorfeld von einem solchen T zu berechnen, da dies nur T (x, y) - (x, y) ist.
Der große Vorteil wäre, dass Sie nur sehr wenige Freiheitsgrade für Ihre Transformation haben, anstatt, wie ich behaupten möchte, 2N Freiheitsgrade im Verschiebungsvektorfeld, wobei N die Anzahl der hellen Punkte ist.
>Wenn es sich tatsächlich um eine affine Transformation handelt, würde ich einen Algorithmus wie diesen vorschlagen:
Aktualisieren
Es scheint, cv2.getAffineTransform erwartet einen umständlichen Eingabedatentyp 'float32'. Nehmen wir an, die Quellkoordinaten sind (sxi,syi)
und das Ziel (dxi,dyi)
mit i=0,1,2
. Was Sie brauchen, ist
Ich glaube nicht, dass eine Kreuzkorrelation hier helfen wird, da es nur eine einzige beste Verschiebung für das gesamte Bild gibt. Es gibt drei Alternativen, die ich in Betracht ziehen würde:
Machen Sie eine Kreuzkorrelation auf Sub-Cluster von Punkten. Nimm zum Beispiel die drei Punkte oben rechts und finde die optimale x-y-Verschiebung durch die Kreuzkorrelation. Dies gibt Ihnen die grobe Transformation für die obere linke Seite. Wiederholen Sie dies für so viele Cluster wie möglich, um eine sinnvolle Karte Ihrer Transformationen zu erhalten. Passen Sie dies mit Ihrer Taylor-Erweiterung an und Sie können sich einigermaßen nahe kommen. Damit Ihre Kreuzkorrelation funktioniert, muss der Unterschied in der Verschiebung zwischen den Punkten jedoch geringer sein als der Punkt, sonst können Sie nicht alle Punkte in einem Cluster gleichzeitig mit einer einzelnen Verschiebung überlappen. Unter diesen Umständen könnte Option 2 besser geeignet sein.
Wenn die Verschiebungen relativ klein sind (was ich für eine Bedingung für Option 1 halte), könnten wir annehmen, dass für einen gegebenen Fleck im linken Bild der nächste Fleck im rechten Bild der entsprechende Fleck ist. Daher finden wir für jeden Punkt im linken Bild den nächsten Punkt im rechten Bild und verwenden diesen als Verschiebung an diesem Ort. Aus den 40 gut verteilten Verschiebungsvektoren können wir durch Anpassen Ihrer Taylor-Expansion eine vernünftige Annäherung an die tatsächliche Verschiebung erhalten.
Dies ist wahrscheinlich die langsamste Methode, könnte aber am robustesten sein, wenn Sie große Verschiebungen haben (und Option 2 funktioniert also nicht): Verwenden Sie so etwas wie einen evolutionären Algorithmus, um die Verschiebung zu finden. Wenden Sie eine zufällige Transformation an, berechnen Sie den verbleibenden Fehler (Sie müssen dies möglicherweise als Summe der kleinsten Entfernung zwischen Punkten in Ihrem ursprünglichen und transformierten Bild definieren) und verbessern Sie die Transformation mit diesen Ergebnissen. Wenn Ihre Verschiebungen ziemlich groß sind, benötigen Sie möglicherweise eine sehr breite Suche, da Sie wahrscheinlich viele lokale Minima in Ihrer Landschaft erhalten werden.
Ich würde Option 2 versuchen, da es scheint, dass Ihre Verschiebungen klein genug sind, um einen Punkt im linken Bild leicht mit einem Fleck im rechten Bild zu assoziieren.
Ich nehme an, dass Ihre Optik nichtlineare Verzerrungen induziert und dass zwei getrennte Strahlengänge (unterschiedliche Filter in jedem?) die Beziehung zwischen den beiden Bildern noch mehr nichtlinear machen. Die affine Transformation, die PiQuer vorschlägt, könnte einen vernünftigen Ansatz ergeben, aber wahrscheinlich niemals die tatsächlichen Verzerrungen vollständig abdecken.
Ich denke, Ihre Annäherung an ein Taylor-Polynom niedriger Ordnung ist in Ordnung. Dies funktioniert für alle meine Anwendungen mit ähnlichen Bedingungen. Höchste Ordnungen sollten wahrscheinlich etwas wie xy ^ 2 und x ^ 2y sein; etwas Höheres als das wirst du nicht bemerken.
Alternativ können Sie die Verzerrungen für jedes Bild zuerst kalibrieren und dann Ihre Experimente durchführen. Auf diese Weise sind Sie nicht von der Verteilung Ihrer Punkte abhängig, sondern können ein Referenzbild mit hoher Auflösung verwenden, um die beste Beschreibung Ihrer Transformation zu erhalten.
Option 2 oben steht immer noch als Vorschlag für die Überlappung der beiden Bilder. Dies kann vollständig automatisiert werden und ich bin mir nicht sicher, was Sie meinen, wenn Sie ein allgemeineres Ergebnis wünschen.
Sie kommentieren, dass die Punkte in den beiden Bildern nicht übereinstimmen. Wenn dies der Fall ist, denke ich, dass Ihr iterativer Kreuzkorrelationsansatz auch nicht sehr robust ist. Sie haben sehr kleine Punkte, so dass Überlappungen nur auftreten, wenn der Unterschied zwischen den beiden Bildern klein ist.
Im Prinzip ist Ihre vorgeschlagene Lösung nicht falsch, aber ob sie funktioniert oder nicht, hängt stark von der Größe Ihrer Deformationen und der Robustheit Ihres Optimierungsalgorithmus ab. Wenn Sie mit sehr wenig Überlappung beginnen, kann es schwierig sein, einen guten Ausgangspunkt für Ihre Optimierung zu finden. Wenn Sie zunächst genügend Überlappungen haben, hätten Sie die Verformung pro Punkt zuerst finden können, aber in einem Kommentar geben Sie an, dass dies nicht funktioniert.
Vielleicht können Sie sich für eine gemischte Lösung entscheiden: Suchen Sie die Kreuzkorrelation von Punktclustern, um einen Ausgangspunkt für Ihre Optimierung zu erhalten, und optimieren Sie dann die Verformung mithilfe der Prozedur, die Sie in Ihrem Update beschrieben haben. Also:
Tags und Links python image cross-correlation