Ich möchte Etiketten auf einem Glas Lebensmittel fotografieren und sie so umwandeln, dass das Etikett flach ist, wobei die Größe der rechten und linken Seite so geändert wird, dass sie mit der Bildmitte übereinstimmt.
Im Idealfall möchte ich den Kontrast zwischen dem Etikett und dem Hintergrund verwenden, um die Kanten zu finden und die Korrektur anzuwenden. Ansonsten kann ich den Benutzer bitten, die Ecken und Seiten des Bildes irgendwie zu identifizieren.
Ich suche nach allgemeinen Techniken und Algorithmen, um ein Bild aufzunehmen, das sphärisch (in meinem Fall zylindrisch) verzerrt ist und das Bild abflachen kann. Gegenwärtig weist das Bild eines Etiketts, das um ein Glas oder eine Flasche gewickelt ist, Merkmale und Text auf, die schrumpfen, wenn es sich rechts oder links vom Bild zurückzieht. Auch die Linien, die den Rand des Etiketts kennzeichnen, sind nur in der Bildmitte parallel und verlaufen am rechten und linken Ende des Etiketts gegeneinander.
Nachdem ich das Bild bearbeitet habe, möchte ich ein fast perfektes Rechteck erhalten, in dem der Text und die Merkmale einheitlich dimensioniert sind, als hätte ich ein Foto des Etiketts aufgenommen, als es nicht auf dem Glas oder der Flasche war.
Außerdem würde es mir gefallen, wenn die Technik die Kanten des Etiketts automatisch erkennen könnte, um die geeignete Korrektur anzuwenden. Andernfalls müsste ich meinen Benutzer bitten, die Etikettengrenzen anzugeben.
Ich habe bereits gegoogelt und Artikel wie diesen gefunden: Abflachen gekrümmter Dokumente , aber ich suche etwas Einfacheres, da ich Etiketten mit einer einfachen Kurve benötige.
quelle
Antworten:
Eine ähnliche Frage wurde bei Mathematica.Stackexchange gestellt . Meine Antwort dort hat sich weiterentwickelt und ist am Ende ziemlich lang geworden, deshalb werde ich den Algorithmus hier zusammenfassen.
Abstrakt
Die Grundidee ist:
Der Algorithmus funktioniert nur für Bilder, bei denen:
Der Algorithmus ist jedoch modular. Zumindest im Prinzip könnten Sie Ihre eigene Etikettenerkennung schreiben, die keinen dunklen Hintergrund erfordert, oder Sie könnten Ihre eigene Qualitätsmessfunktion schreiben, die mit elliptischen oder achteckigen Etiketten umgehen kann.
Ergebnisse
Diese Bilder wurden vollautomatisch verarbeitet, dh der Algorithmus nimmt das Quellbild auf, arbeitet einige Sekunden und zeigt dann das Mapping (links) und das unverzerrte Bild (rechts):
Die nächsten Bilder wurden mit einer modifizierten Version des Algorithmus verarbeitet, wobei der Benutzer den linken und den rechten Rand des Glases (nicht das Etikett) auswählte, da die Krümmung des Etiketts nicht aus dem Bild in einer Frontalaufnahme (dh dem Ein vollautomatischer Algorithmus würde Bilder zurückgeben, die leicht verzerrt sind.
Implementierung:
1. Suchen Sie das Etikett
Das Etikett ist hell vor einem dunklen Hintergrund, sodass ich es mithilfe der Binarisierung leicht finden kann:
Ich wähle einfach die größte verbundene Komponente aus und gehe davon aus, dass dies die Bezeichnung ist:
2. Finden Sie die Ränder des Etiketts
Nächster Schritt: Finden Sie die oberen / unteren / linken / rechten Ränder mit einfachen abgeleiteten Faltungsmasken:
Dies ist eine kleine Hilfsfunktion, die alle weißen Pixel in einem dieser vier Bilder findet und die Indizes in Koordinaten umwandelt (
Position
gibt Indizes zurück, und Indizes sind 1-basierte {y, x} -Tupel, wobei y = 1 am oberen Rand von steht Alle Bildverarbeitungsfunktionen erwarten jedoch Koordinaten, die auf 0-basierenden {x, y} -Tupeln basieren (wobei y = 0 der untere Teil des Bildes ist):3. Suchen Sie eine Zuordnung von Bild zu Zylinderkoordinaten
Jetzt habe ich vier separate Koordinatenlisten für den oberen, unteren, linken und rechten Rand des Etiketts. Ich definiere eine Zuordnung von Bildkoordinaten zu Zylinderkoordinaten:
Dies ist eine zylindrische Abbildung, die X / Y-Koordinaten im Quellbild auf zylindrische Koordinaten abbildet. Die Zuordnung hat 10 Freiheitsgrade für Höhe / Radius / Mitte / Perspektive / Neigung. Ich habe die Taylor-Reihe verwendet, um den Arcussinus zu approximieren, da die Optimierung nicht direkt mit ArcSin funktioniert. Das
Clip
Anrufe sind mein Ad-hoc-Versuch, komplexe Nummern während der Optimierung zu verhindern. Hier gibt es einen Kompromiss: Einerseits sollte die Funktion einer exakten zylindrischen Abbildung so nahe wie möglich kommen, um eine möglichst geringe Verzerrung zu erzielen. Wenn es andererseits zu kompliziert ist, wird es viel schwieriger, automatisch optimale Werte für die Freiheitsgrade zu finden. (Das Schöne an der Bildverarbeitung mit Mathematica ist, dass Sie mit solchen mathematischen Modellen sehr einfach herumspielen, zusätzliche Begriffe für verschiedene Verzerrungen einfügen und dieselben Optimierungsfunktionen verwenden können, um endgültige Ergebnisse zu erzielen. Ich habe noch nie etwas tun können so mit OpenCV oder Matlab. Aber ich habe die symbolische Toolbox für Matlab nie ausprobiert, vielleicht macht das es nützlicher.)Als nächstes definiere ich eine "Fehlerfunktion", die die Qualität eines Bildes misst -> Zylinderkoordinatenzuordnung. Es ist nur die Summe der Fehlerquadrate für die Randpixel:
Diese Fehlerfunktion misst die "Qualität" einer Zuordnung: Sie ist am niedrigsten, wenn die Punkte am linken Rand (0 / [irgendetwas]) zugeordnet sind, Pixel am oberen Rand ([irgendetwas] / 0) usw. .
Jetzt kann ich Mathematica anweisen, Koeffizienten zu finden, die diese Fehlerfunktion minimieren. Ich kann über einige der Koeffizienten "Vermutungen anstellen" (z. B. den Radius und die Mitte des Glases im Bild). Ich benutze diese als Ausgangspunkte für die Optimierung:
FindMinimum
findet Werte für die 10 Freiheitsgrade meiner Zuordnungsfunktion, die die Fehlerfunktion minimieren. Kombiniere das generische Mapping und diese Lösung und ich erhalte ein Mapping von X / Y-Bildkoordinaten, das zum Beschriftungsbereich passt. Ich kann dieses Mapping mit derContourPlot
Funktion von Mathematica visualisieren :4. Transformieren Sie das Bild
Schließlich verwende ich Mathematics
ImageForwardTransform
Funktion, um das Bild gemäß dieser Zuordnung zu verzerren:Das ergibt die oben gezeigten Ergebnisse.
Manuell unterstützte Version
Der obige Algorithmus ist vollautomatisch. Keine Anpassungen erforderlich. Es funktioniert einigermaßen gut, solange das Bild von oben oder unten aufgenommen wird. Wenn es sich jedoch um eine Frontalaufnahme handelt, kann der Radius des Glases nicht anhand der Form des Etiketts geschätzt werden. In diesen Fällen erhalte ich viel bessere Ergebnisse, wenn der Benutzer den linken / rechten Rand des Glases manuell eingibt und die entsprechenden Freiheitsgrade im Mapping explizit einstellt.
Mit diesem Code kann der Benutzer den linken / rechten Rand auswählen:
Dies ist der alternative Optimierungscode, bei dem Mittelpunkt und Radius explizit angegeben werden.
quelle