Convert contour paths to svg paths
Asked Answered
S

2

13

I am using openCV with python to extract contours from an image. Now I need to export these contour paths (list) as an svg paths. How can I achieve this ?

code:

ret,thresh = cv2.threshold(imgray,27,25,0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL , cv2.CHAIN_APPROX_TC89_L1)
print(type(contours)) #type list
Sheryl answered 30/3, 2017 at 4:45 Comment(2)
What is the the aspect you are having difficulties with exactly? You have a vector of contours, you iterate through them converting them to SVG path statements and writing them to a text file w3schools.com/graphics/svg_path.asp You may need to make an initial pass to know the maximum dimensions for your page-size, or you just use the dimensions of your original image on which you found the contours.Norahnorbert
@MarkSetchell Thank you for the hint. I was being too lazy :)Sheryl
S
20

the problem has been solved as follows:

c = max(contours, key=cv2.contourArea) #max contour
f = open('path.svg', 'w+')
f.write('<svg width="'+str(width)+'" height="'+str(height)+'" xmlns="http://www.w3.org/2000/svg">')
f.write('<path d="M')

for i in xrange(len(c)):
    #print(c[i][0])
    x, y = c[i][0]
    print(x)
    f.write(str(x)+  ' ' + str(y)+' ')

f.write('"/>')
f.write('</svg>')
f.close()
Sheryl answered 30/3, 2017 at 9:30 Comment(6)
Well done - and thank you for sharing back your code with the community.Norahnorbert
@MarkSetchell, I also reduced the vertices of the contours using cv2.approxPolyDP() , now I need to find a way to smoothed the lines.Sheryl
A (not very elegant) possibility may be to draw the paths into an image and the use potrace to smooth that... potrace.sourceforge.netNorahnorbert
@MarkSetchell I am not trying to draw paths 'over' and image. For my problem, I need to extract the paths as a vector format so that I can use it elsewhere as an svg.Sheryl
I was suggesting you create a temporary image with the unsmoothed contours on it and then let potrace convert that to a smoothed SVG file.Norahnorbert
in my case i had to add the first point at the end to close the contour.Grishilda
D
5

The other answer only save the outmost contour in svg file, which is not my case. To save all the contours found by opencv, you could instead do this:

with open("path.svg", "w+") as f:
    f.write(f'<svg width="{w}" height="{h}" xmlns="http://www.w3.org/2000/svg">')

    for c in contours:
        f.write('<path d="M')
        for i in range(len(c)):
            x, y = c[i][0]
            f.write(f"{x} {y} ")
        f.write('" style="stroke:pink"/>')
    f.write("</svg>")
Doggerel answered 8/8, 2019 at 23:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.