foto vektorisieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
BananaBowser
User
Beiträge: 7
Registriert: Mittwoch 26. Oktober 2016, 09:28

Hallo Leute,

ich möchte mit Python Fotos vektorisieren. Suche gerade zu diesem Zweck passende Bibliotheken die man nutzen könnte.
Habt ihr schon in dem Bereich Erfahrungen gesammelt?

Grüße
BlackJack

Es gibt eine Pythonanbindung an die Bibliothek von ``potrace``: https://github.com/flupke/pypotrace
BananaBowser
User
Beiträge: 7
Registriert: Mittwoch 26. Oktober 2016, 09:28

schau ich mir an! vielen dank schonmal!
BananaBowser
User
Beiträge: 7
Registriert: Mittwoch 26. Oktober 2016, 09:28

hallo nochmal,

bin noch in den Programmier-Kinderschuhen und komme mit der potrace Bibliothek nicht ganz zurecht.

Kann mir jemand das beispiel von git etwas genauer erklären?

Code: Alles auswählen

import numpy as np
import potrace

# Make a numpy array with a rectangle in the middle
data = np.zeros((32, 32), np.uint32)
data[8:32-8, 8:32-8] = 1

# Create a bitmap from the array
bmp = potrace.Bitmap(data)

# Trace the bitmap to a path
path = bmp.trace()

# Iterate over path curves
for curve in path:
    print "start_point =", curve.start_point
    for segment in curve:
        print segment
        end_point_x, end_point_y = segment.end_point
        if segment.is_corner:
            c_x, c_y = segment.c
        else:
            c1_x, c1_y = segment.c1
            c2_x, c2_y = segment.c2
Oder evtl an einem Mini-Beispiel deutlich machen wie ich so ein Bitmap vektorisieren kann. Hab bislang nur auf Kommandozeilenebene mit potrace etwas hinbekommen...ein Mini-Beispiel für die Kommandozeile:

Code: Alles auswählen

cat foto.bmp |
mkbitmap -x -f 4 -s 2 -t 0.48 |
potrace -b eps -o foto.eps |
pstoedit -f plot-hpgl foto.hpgl
Danke für jede Hilfe
Zuletzt geändert von Anonymous am Montag 31. Oktober 2016, 16:41, insgesamt 1-mal geändert.
Grund: Quelltext in Codebox-Tags gesetzt.
BlackJack

@BananaBowser: Was genau verstehst Du denn nicht? `potrace` ist ja ziemlich, äh, übersichtlich. :-) Die Bibliothek enthält nur den Algorithmus um aus einer Bitmap Kurven zu machen. Die zwei Arten von Segmenten enthalten, Bezier und ”Ecken”. Von beiden ist in der Dokumentation zu dem Python-Modul jeweils eine Graphik wo die Punkte zu sehen sind, die man von den Segment-Objekten abfragen kann.

Die Bibliothek enthält sonst nichts weiter. Also sowohl für das bereitstellen der Eingabedaten als auch für das erstellen von Ausgabedaten ist man selbst verantwortlich.

Der Beispielcode ist enthält ab Zeile 19 nicht wirklich sinnvollen Code weil der nichts (sichtbares) tut. Das sieht man nur wie man die beiden Segmenttypen unterscheidet und wie man die Koordinaten an Namen binden kann. An der Stelle müsstest Du dann irgend etwas mit den Koordinaten anstellen.

Die `Curve`-Objekte besitzen auch eine `tesselate()`-Methode mit der man sich Punkte geben lassen kann welche die Kurve als Linienzug annähern. Falls man mit einer solchen Darstellung der Daten mehr anfangen kann.

Was willst Du denn eigentlich machen?
BananaBowser
User
Beiträge: 7
Registriert: Mittwoch 26. Oktober 2016, 09:28

BlackJack hat geschrieben:@BananaBowser: Was genau verstehst Du denn nicht?
Einiges :D

Im Code Zeile 5 wird ein array mit nullen erstellt? Wenn ja, wozu?
Zeile 6 verstehe ich momentan noch gar nicht. Morgen früh werde ich mir aber mal numpy anschauen. Bin ich bislang nicht zu gekommen.

BlackJack hat geschrieben:
Die Bibliothek enthält sonst nichts weiter. Also sowohl für das bereitstellen der Eingabedaten als auch für das erstellen von Ausgabedaten ist man selbst verantwortlich.
Hätte jetzt gedacht, dass ich als Eingabedaten ein handelsübliches Bitmap- Foto nutzen kann.
Inwiefern hat das mit Zeile 9 zu tun? Wie kann ich das verstehen, also wie wird ein Bitmap aus einem array erzeugt?
Hast du diesbezüglich ein Stichwort? Weiß nicht wo ich anfangen soll zu suchen.
BlackJack hat geschrieben:Die `Curve`-Objekte besitzen auch eine `tesselate()`-Methode mit der man sich Punkte geben lassen kann welche die Kurve als Linienzug annähern. Falls man mit einer solchen Darstellung der Daten mehr anfangen kann.

Was willst Du denn eigentlich machen?
Das mit dem tesselate() werde ich mir bei Gelegenheit näher anschauen.

Ich möchte ein Foto vektorisieren, es dann z.B. ins hpgl format bringen um daraus x,y,z-Koordinaten zu extrahieren. Diese wiederum speise ich in ein 6-Achsigen ABB Roboter, der dann das Foto wahlweise malen bzw fräsen soll.

Per Kommandozeile hab ich es auch schon geschafft die Daten zu extrahieren und den Roboter kann ich damit auch schon füttern :)
Mit Python will ich das ganze nun aber etwas effizienter gestalten und im Endeffekt vollautomatisch ablaufen lassen. Leider hab ich bis vor 2 Wochen nur mal im Studium für ein Semester Grundlagen in C gelernt und muss mich jetzt erstmal ein wenig zurecht finden.

Danke schonmal für deine Hilfe
BlackJack

@BananaBowser: Das Array mit den Nullen ist die Bitmap. In der nächsten Zeile wird dort mit einem Anstand von 8 Pixeln vom Rand eine quadratische Box ”gezeichnet”. Also mit 1en gefüllt.

Zeile 9 hat nichts mit dem BMP-Dateiformat zu tun. Das ist einfach ein Datentyp von `potrace` um eine Bitmap darzustellen, also ein Rasterbild mit gesetzten und nicht gesetzten Punkten. Das wird als Numpy-Array übergeben. Wie man zu so einem Array kommt wenn man eine Bilddatei vorliegen hat, wird in der Dokumentation angedeutet: Ein Bild mit der Python Imaging Library (`PIL`) oder dem etwas lebendigeren Pillow-Package (hat auch den Namen `PIL` und ist von der API her kompatibel) laden. Damit kann man auch Bilder in Bitmaps umwandeln und diverse Filter anwenden. Und man kann die Daten als Numpy-Array bekommen.

Ist das HPGL-Format als Zwischenschritt wichtig? Wenn man das mit dem `potrace`-Modul macht, müsste man die HPGL-Daten ja selbst programmatisch erzeugen. Dann könnte man vielleicht auch gleich das Endergebnis erzeugen und sich den Zwischenschritt sparen. Oder man erzeugt ein Zwischenergebnis das nicht so viele Steuerbefehle wie die ``pstoedit``-Ausgabe enthält, die ja wahrscheinlich sowieso nicht komplett vom Roboter verstanden wird.
BananaBowser
User
Beiträge: 7
Registriert: Mittwoch 26. Oktober 2016, 09:28

@BlackJack:

Super vielen Dank, für die vielen nützlichen Informationen. Werde mir dann heute mal das Pillow-Package anschauen um die Daten als numpy-array zu bekommen.

Wegen der Ausgabe und des HPGL-Formats: Habe das mit potrace deshalb genutzt, weil man aus diesem sehr einfach die xyz-Koordinaten rausholen kann. (und ja die Daten musste ich noch ein wenig für den Roboter aufarbeiten) Ich gehe davon aus, dass man dieses als Zwischenschritt nicht zwingend braucht bislang hab ich mich aber zu wenig mit vektorisierten Fotos beschäftigt um eine Idee zu haben, wie ich mir selbst direkt Koordinaten erzeugen kann.
BananaBowser
User
Beiträge: 7
Registriert: Mittwoch 26. Oktober 2016, 09:28

Hello again :D

mein plan sieht aktuell so aus, dass ich die Bezier-Kurven über ein De-Casteljau Algorithmus werfe und so an x,y Koordinaten der Kurven komme.

Wenn ich potrace mit Daten füttere und wie im Beispielcode Zeile 18 mir print segment anzeigen lasse kommt so etwas bei raus:

Code: Alles auswählen

start_point = (0.0, 180.0)
CornerSegment(c=(0.0, 0.0), end_point=(270.0, 0.0))
CornerSegment(c=(540.0, 0.0), end_point=(540.0, 180.0))
CornerSegment(c=(540.0, 360.0), end_point=(270.0, 360.0))
CornerSegment(c=(0.0, 360.0), end_point=(0.0, 180.0))
start_point = (313.0, 153.55901699437493)
BezierSegment(c1=(313.0, 153.31647634128117), c2=(312.55, 152.83991869381245), end_point=(312.0, 152.5))
BezierSegment(c1=(311.45, 152.16008130618755), c2=(311.0, 152.35852365871884), end_point=(311.0, 152.94098300562507))
BezierSegment(c1=(311.0, 153.52344235253128), c2=(311.45, 154.0), end_point=(312.0, 154.0))
BezierSegment(c1=(312.55, 154.0), c2=(313.0, 153.8015576474687), end_point=(313.0, 153.55901699437493))
jetzt hätte ich gedacht, das segment eine variable vom typ string ist und wollte mit Hilfe der str.find() funktion mir die passenden punkte rausholen. Da segment laut Python aber ein potrace.cornersegment ist klappt das ganze nicht.

Wie komme ich also an die punkte heran? :?
BlackJack

@BananaBowser: Na in genau dem Beispielcode siehst Du doch das `CornerSegment`-Exemplare ein `c`-Attribut haben wo der Kontrollpunkt hinterlegt ist.
BananaBowser
User
Beiträge: 7
Registriert: Mittwoch 26. Oktober 2016, 09:28

:shock: an manchen Tagen besser im bett bleiben oder nicht so viele Dinge parallel machen...Vielen Dank fürs Augen öffnen!
Antworten