[Python] PNG image to vector graphic conversion method with recognition of 1px lines?

Discussão em 'Python' iniciado por Stack, Maio 27, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to find a way to convert a .png image with 1px lines to a vector file. The issue I am having is that my approaches are very inconsistent due to the thin lines I am trying to recognize.

    One idea was to use potrace, but I get very blobby results.

    The other was to use OpenCV, with the result that OpenCV does not recognize all lines.

    An example file I am trying to convert is this:

    https://geoservices.bayern.de/od/wm...00,48.145000,11.565000&WIDTH=2048&HEIGHT=2048

    Is there any other way to convert this to a vector file automatically?

    i gave opencv another try and made it much further:

    import sys
    import cv2
    import numpy as np
    import svgwrite
    import os

    def raster_to_svg(input_path, output_path=None, simplify=False):
    img = cv2.imread(input_path, cv2.IMREAD_GRAYSCALE)
    if img is None:
    print(f"Fehler: Bild konnte nicht geladen werden: {input_path}")
    return

    inv = cv2.bitwise_not(img)

    _, thresh = cv2.threshold(inv, 127, 255, cv2.THRESH_BINARY)

    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    height, width = img.shape
    if not output_path:
    output_path = os.path.splitext(input_path)[0] + "_white_areas.svg"
    dwg = svgwrite.Drawing(output_path, size=(width, height))

    for contour in contours:
    if len(contour) < 3:
    continue # Kein gültiges Polygon

    points = [(int(p[0][0]), int(p[0][1])) for p in contour]

    if simplify:
    epsilon = 1.0 # Toleranz für Polygonvereinfachung
    approx = cv2.approxPolyDP(contour, epsilon, True)
    points = [(int(p[0][0]), int(p[0][1])) for p in approx]

    dwg.add(dwg.polygon(points=points, fill='white', stroke='black', stroke_width=0.1))

    dwg.save()
    print(f"SVG gespeichert unter: {output_path}")

    if __name__ == "__main__":
    if len(sys.argv) < 2:
    print("Verwendung: python raster_to_svg.py bild.png [output.svg]")
    else:
    input_file = sys.argv[1]
    output_file = sys.argv[2] if len(sys.argv) > 2 else None
    raster_to_svg(input_file, output_file)


    but now i am struggling with the way pixels are represented: source: [​IMG]

    result: [​IMG] [​IMG]

    any idea how i could make these lines straight lines?

    Thanks a lot!!

    Continue reading...

Compartilhe esta Página