프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / DTI_PID / DTI_PID / potrace.py @ 35d6d96c

이력 | 보기 | 이력해설 | 다운로드 (4.33 KB)

1
#!/usr/bin/env/python3
2
# coding: utf-8
3

    
4
import numpy as np, cv2, subprocess
5
import os, sys
6
from xml.dom import minidom
7
import svg.path
8
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree
9
import SymbolBase
10
from shapely.geometry import LineString
11
from shapely.ops import linemerge
12
from LineDetector import LineDetector
13

    
14
# potrace command
15
POTRACE = os.path.dirname(os.path.realpath(__file__)) + '\\potrace.exe'
16
ADJUST = 10
17

    
18
def convertImageToSvg(imgFilePath, destFilePath):
19
    thresh = 127
20

    
21
    image  = cv2.imread(imgFilePath, cv2.IMREAD_GRAYSCALE)
22
    threshold = cv2.threshold(image, thresh, 255, cv2.THRESH_BINARY)[1]
23
    kernel = np.ones((3, 3), np.uint8)
24
    erode = cv2.dilate(threshold, kernel, iterations=1)
25

    
26
    # convert to bmp binary so that potrace can handle it
27
    retval, buf = cv2.imencode('.bmp', erode)
28
    if retval == False:
29
        raise ValueError('Failed to convert into BMP binary data')
30
    # convert buf from numpy.ndarray to bytes
31
    binbmp = buf.tobytes()
32
    
33
    args = [
34
        POTRACE,
35
        '-', '-o-', '--svg'
36
    ]
37
    
38
    p = subprocess.Popen(
39
        args,
40
        stdin=subprocess.PIPE,
41
        stdout=subprocess.PIPE,
42
        stderr=subprocess.PIPE,
43
        shell=False
44
    )
45
        
46
    stdout, stderr = p.communicate(input=binbmp)
47
    if len(stderr) != 0:
48
        raise RuntimeError('Potrace threw error:\n' + stderr.decode('utf-8'))
49
    
50
    svgData = stdout
51
    #svgData = stdout.decode("utf-8")
52
    #svgData = stdout.decode("utf-16")
53
    #svgData = svgData.replace(u"\u000B", u"")
54
    #svgData = svgData.encode("utf-8")
55

    
56
    xmlFile = open(destFilePath, "wb")#, encoding = "utf-8")
57
    xmlFile.write(svgData)
58
    xmlFile.close()
59

    
60
# extract line from image by using potrace
61
def passpotrace(imgFile):
62
    thresh = 127
63

    
64
    image  = cv2.imread(imgFile, cv2.IMREAD_GRAYSCALE)
65
    threshold = cv2.threshold(image, thresh, 255, cv2.THRESH_BINARY)[1]
66
    kernel = np.ones((3, 3), np.uint8)
67
    erode = cv2.dilate(threshold, kernel, iterations=1)
68

    
69
    # convert to bmp binary so that potrace can handle it
70
    retval, buf = cv2.imencode('.bmp', erode)
71
    if retval == False:
72
        raise ValueError('Failed to convert into BMP binary data')
73
    # convert buf from numpy.ndarray to bytes
74
    binbmp = buf.tobytes()
75
    
76
    args = [
77
        POTRACE,
78
        '-', '-o-', '--svg'
79
    ]
80
    
81
    p = subprocess.Popen(
82
        args,
83
        stdin=subprocess.PIPE,
84
        stdout=subprocess.PIPE,
85
        stderr=subprocess.PIPE,
86
        shell=False
87
        )
88
        
89
    stdout, stderr = p.communicate(input=binbmp)
90
    if len(stderr) != 0:
91
        raise RuntimeError('Potrace threw error:\n' + stderr.decode('utf-8'))
92

    
93
    imgLines = []
94
    # parse svg data and extract lines
95
    svgdom = minidom.parseString(stdout)
96
    transform = svgdom.getElementsByTagName('g')[0].getAttribute('transform')
97
    translate = transform.split(' ')[0].split('translate')[1].split(',')
98
    dx = float(translate[0][1:])
99
    dy = float(translate[1][:-1])
100
    scale = transform.split(' ')[1].split('scale')[1].split(',')
101
    sx = float(scale[0][1:])
102
    sy = float(scale[1][:-1])
103

    
104
    pathstrings = [path.getAttribute('d') for path in svgdom.getElementsByTagName('path')]
105
    for pathstring in pathstrings:
106
        pathdata = svg.path.parse_path(pathstring)
107
        for segment in pathdata:
108
            if type(segment) is svg.path.Line:
109
                line = LineString([(segment.start.real / ADJUST, segment.start.imag / ADJUST), (segment.end.real / ADJUST, segment.end.imag / ADJUST)])
110
                imgLines.append(line)
111
    # up to here
112
    return imgLines
113
    
114
if __name__ == '__main__':
115
    execpath = os.path.dirname(os.path.realpath(__file__))
116

    
117
    path = execpath + '\\res\\UY1-K-2007_P1_300dpi_black.png'
118
    #lines = linedraw.sketch(path)
119
    #linedraw.visualize(lines)
120
#    path = sys.argv[1]  # 1 argument given is a string for the path of drawing
121
    #imgLines = passpotrace(path)    #execpath + '\\res\\UY1-K-2007_P1_300dpi_black.png')
122
    image  = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
123
    lineDetector = LineDetector(image)
124
    lineDetector.Detect()
125
    
126
    try:
127
        xmlFilePath = os.path.dirname(path) + '\\' + os.path.basename(path).split('.')[0] + '.xml'
128
        file = open(xmlFilePath, 'w')
129
        for line in imgLines:
130
            file.write(str(line) + '\n')
131
        file.close()
132
    except Exception as ex:
133
        print('에러가 발생했습니다.\n', ex)
클립보드 이미지 추가 (최대 크기: 500 MB)