def _finalize_strokes(self, strokes, lines=None): """ Lines just used to determine if line is trivial/vacuous DOES not convert EOS to SOS """ for i, offsets in tqdm(enumerate(strokes)): if lines and not lines[i]: print("Empty line? Stroke:") print(offsets[:10]) continue offsets[:, :2] *= 1.5 curr_strokes = drawing.offsets_to_coords(offsets) curr_strokes = drawing.denoise(curr_strokes) curr_strokes[:, :2] = drawing.align(curr_strokes[:, :2]) # Normalize curr_strokes[:, 1] -= np.min(curr_strokes[:, 1]) max_y = np.max(curr_strokes[:, 1]) if max_y: curr_strokes[:, :2] /= max_y else: warnings.warn(f"max y is zero {curr_strokes}") # Convert end points to start points #curr_strokes = eos_to_sos(curr_strokes) yield curr_strokes
def _align_strokes( self, offsets, align_strokes=True, denoise_strokes=True, interpolation_factor=None, cnc_format=True, do_plot=False ): strokes = drawing.offsets_to_coords(offsets) if denoise_strokes: strokes = drawing.denoise(strokes) if interpolation_factor is not None: strokes = drawing.interpolate(strokes, factor=interpolation_factor) if align_strokes: strokes[:, :2] = drawing.align(strokes[:, :2]) if do_plot: fig, ax = plt.subplots(figsize=(12, 3)) stroke = [] for x, y, eos in strokes: stroke.append((x, y)) if eos == 1: coords = tuple(zip(*stroke)) ax.plot(coords[0], coords[1], 'y') stroke = [] if stroke: coords = tuple(zip(*stroke)) ax.plot(coords[0], coords[1], 'y') stroke = [] ax.set_xlim(-50, 600) ax.set_ylim(-40, 40) ax.set_aspect('equal') plt.tick_params( axis='both', left='off', top='off', right='off', bottom='off', labelleft='off', labeltop='off', labelright='off', labelbottom='off' ) plt.show() plt.close('all') if cnc_format: strokes = self._stroke_to_cnc_format(strokes) return strokes
def get_stroke_sequence(filename, resample=False, first_stroke_0=False): tree = ElementTree.parse(filename).getroot() strokes = [i for i in tree if i.tag == 'StrokeSet'][0] coords = [] for stroke in strokes: for i, point in enumerate(stroke): coords.append([ int(point.attrib['x']), -1 * int(point.attrib['y']), int(i == len(stroke) - 1) ]) coords = np.array(coords) # coords2 = drawing.align(coords.copy()) # coords2 = drawing.denoise(coords) # offsets2 = drawing.coords_to_offsets(coords2) # #offsets = offsets[:drawing.MAX_STROKE_LEN] These are excluded later, truncating them would prevent exclusion # offsets2 = drawing.normalize(offsets2) if resample: coords = utils.resample_coords(coords) coords = drawing.align(coords) coords = drawing.denoise(coords) offsets = drawing.coords_to_offsets(coords, first_stroke_0=first_stroke_0) #offsets = offsets[:drawing.MAX_STROKE_LEN] These are excluded later, truncating them would prevent exclusion offsets = drawing.normalize(offsets) return coords, offsets
def _draw(self, strokes, lines, filename, stroke_colors=None, \ stroke_widths=None, background_color='white'): stroke_colors = stroke_colors or ['black']*len(lines) stroke_widths = stroke_widths or [2]*len(lines) line_height = 55 view_width = 0 width_padding = 40 view_height = line_height*(len(strokes) + 1) dwg = svgwrite.Drawing(filename=filename) #dwg.add(dwg.rect(insert=(0, 0), size=(view_width, view_height), fill=background_color)) initial_coord = np.array([0, -(3*line_height / 4)]) for offsets, line, color, width in zip(strokes, lines, stroke_colors, stroke_widths): if not line: initial_coord[1] -= line_height continue line_class = "linestart" offsets[:, :2] *= 1.5 strokes = drawing.offsets_to_coords(offsets) strokes = drawing.denoise(strokes) strokes[:, :2] = drawing.align(strokes[:, :2]) strokes[:, 1] *= -1 strokes[:, :2] -= strokes[:, :2].min() + initial_coord #strokes[:, 0] += (view_width - strokes[:, 0].max()) / 2 # center text prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*strokes.T): if x > view_width: view_width = x # p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) # create a new path each time we move if prev_eos == 1.0: path = svgwrite.path.Path(p) path = path.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path) p = '{}{},{} '.format('M', x, y) else: p += '{}{},{} '.format('L', x, y) prev_eos = eos path = svgwrite.path.Path(p) path = path.stroke(color=color, width=width, linecap='round').fill("none") if line_class != None: path.update({'class_': line_class}) line_class = None dwg.add(path) initial_coord[1] -= line_height view_width = int(view_width + width_padding) dwg.viewbox(width=view_width, height=view_height) dwg.save()
def _draw(self, strokes, lines, filename=None, fileobj=None, stroke_colors=None, stroke_widths=None): stroke_colors = stroke_colors or ['black'] * len(lines) stroke_widths = stroke_widths or [2] * len(lines) line_height = 60 view_width = 1000 view_height = line_height * (len(strokes) + 1) dwg = svgwrite.Drawing(filename=filename) dwg.viewbox(width=view_width, height=view_height) dwg.add( dwg.rect(insert=(0, 0), size=(view_width, view_height), fill='white')) initial_coord = np.array([0, -(3 * line_height / 4)]) for offsets, line, color, width in zip(strokes, lines, stroke_colors, stroke_widths): if not line: initial_coord[1] -= line_height continue offsets[:, :2] *= 1.5 strokes = drawing.offsets_to_coords(offsets) strokes = drawing.denoise(strokes) strokes[:, :2] = drawing.align(strokes[:, :2]) strokes[:, 1] *= -1 strokes[:, :2] -= strokes[:, :2].min() + initial_coord strokes[:, 0] += (view_width - strokes[:, 0].max()) / 2 prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*strokes.T): p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) prev_eos = eos path = svgwrite.path.Path(p) path = path.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path) initial_coord[1] -= line_height if filename: dwg.save() elif fileobj: dwg.write(fileobj) else: assert False
def get_stroke_sequence(sampleStrokes): strokes = sampleStrokes coords = [] if strokes[0][2] < 0.5: coords = [[0, 0, 1]] for i, point in enumerate(strokes): coords.append([int(point[0]), -1 * int(point[1]), point[2]]) coords = np.array(coords) coords = drawing.align(coords) coords = drawing.denoise(coords) offsets = drawing.coords_to_offsets(coords) offsets = offsets[:drawing.MAX_STROKE_LEN] offsets = drawing.normalize(offsets) return offsets
def preprocess(sampleStrokes): strokes = sampleStrokes coords = [] if strokes[0].penUp < 0.5: coords = [[0, 0, 1]] for i, point in enumerate(strokes): coords.append([int(point.pos[0]), -1 * int(point.pos[1]), point.penUp]) coords = np.array(coords) coords = drawing.align(coords) coords = drawing.denoise(coords) offsets = drawing.coords_to_offsets(coords) offsets = offsets[:drawing.MAX_STROKE_LEN] offsets, normalizationFactor = drawing.normalize( offsets, returnNormalizationFactor=True) return offsets, normalizationFactor
def get_stroke_sequence(filename): tree = ElementTree.parse(filename).getroot() strokes = [i for i in tree if i.tag == 'StrokeSet'][0] coords = [] for stroke in strokes: for i, point in enumerate(stroke): coords.append([ int(point.attrib['x']), -1 * int(point.attrib['y']), int(i == len(stroke) - 1) ]) coords = np.array(coords) coords = drawing.align(coords) coords = drawing.denoise(coords) offsets = drawing.coords_to_offsets(coords) offsets = offsets[:drawing.MAX_STROKE_LEN] offsets = drawing.normalize(offsets) return offsets
def get_stroke_sequence(filename): tree = ElementTree.parse(filename).getroot() strokes = [i for i in tree if i.tag == 'StrokeSet'][0] coords = [] for stroke in strokes: for i, point in enumerate(stroke): coords.append([ int(point.attrib['x']), -1*int(point.attrib['y']), int(i == len(stroke) - 1) ]) coords = np.array(coords) coords = drawing.align(coords) coords = drawing.denoise(coords) offsets = drawing.coords_to_offsets(coords) offsets = offsets[:drawing.MAX_STROKE_LEN] offsets = drawing.normalize(offsets) return offsets
def _draw(self, strokes, lines, filename, stroke_colors=None, stroke_widths=None): stroke_colors = stroke_colors or ['black']*len(lines) stroke_widths = stroke_widths or [2]*len(lines) line_height = 60 view_width = 1000 view_height = line_height*(len(strokes) + 1) dwg = svgwrite.Drawing(filename=filename) dwg.viewbox(width=view_width, height=view_height) dwg.add(dwg.rect(insert=(0, 0), size=(view_width, view_height), fill='white')) initial_coord = np.array([0, -(3*line_height / 4)]) for i, (offsets, line, color, width) in tqdm(enumerate(zip(strokes, lines, stroke_colors, stroke_widths))): if not line: # insert return character initial_coord[1] -= line_height continue offsets = offsets.copy() offsets[:, :2] *= 1.5 curr_strokes = drawing.offsets_to_coords(offsets) curr_strokes = drawing.denoise(curr_strokes) curr_strokes[:, :2] = drawing.align(curr_strokes[:, :2]) curr_strokes[:, 1] *= -1 curr_strokes[:, :2] -= curr_strokes[:, :2].min() + initial_coord curr_strokes[:, 0] += (view_width - curr_strokes[:, 0].max()) / 2 prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*curr_strokes.T): p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) prev_eos = eos path = svgwrite.path.Path(p) path = path.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path) initial_coord[1] -= line_height dwg.save() return strokes
def offsets2coords(self, offsets, filename): offsets = drawing.offsets_to_coords(offsets[0]) offsets = drawing.denoise(offsets) offsets[:, :2] = drawing.align(offsets[:, :2]) offsets[:, 1] *= -1 offsets[:, :2] -= offsets[:, :2].min() detachments = [-1] + list(np.where(offsets[:, 2])[0]) coords = np.array([ offsets[detachments[i] + 1:detachments[i + 1], :2] for i in range(len(detachments) - 1) ]) self.counter.update({filename: coords}) current_length = len(self.counter) if current_length % 5000 == 0 or current_length == self.length: self.prt += 1 pickle.dump( self.counter, open(self.path + '/strokes_prt_%s.pickle.dat' % self.prt, 'wb')) self.counter = {}
def _draw(self, strokes, lines, filename, stroke_colors=None, stroke_widths=None): stroke_colors = stroke_colors or ['black']*len(lines) stroke_widths = stroke_widths or [2]*len(lines) line_height = 60 view_width = 1000 view_height = line_height*(len(strokes) + 1) dwg = svgwrite.Drawing(filename=filename) dwg.viewbox(width=view_width, height=view_height) dwg.add(dwg.rect(insert=(0, 0), size=(view_width, view_height), fill='white')) initial_coord = np.array([0, -(3*line_height / 4)]) for offsets, line, color, width in zip(strokes, lines, stroke_colors, stroke_widths): if not line: initial_coord[1] -= line_height continue offsets[:, :2] *= 1.5 strokes = drawing.offsets_to_coords(offsets) strokes = drawing.denoise(strokes) strokes[:, :2] = drawing.align(strokes[:, :2]) strokes[:, 1] *= -1 strokes[:, :2] -= strokes[:, :2].min() + initial_coord strokes[:, 0] += (view_width - strokes[:, 0].max()) / 2 prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*strokes.T): p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) prev_eos = eos path = svgwrite.path.Path(p) path = path.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path) initial_coord[1] -= line_height dwg.save()
def draw(strokes, lines, filename, align=True, denoise=True): line_height = 60 view_width = 1000 view_height = line_height * (len(strokes) + 1) dwg = svgwrite.Drawing(filename=filename) dwg.viewbox(width=view_width, height=view_height) dwg.add( dwg.rect(insert=(0, 0), size=(view_width, view_height), fill='white')) initial_coord = np.array([0, -line_height]) for offsets, line in zip(strokes, lines): if not line: initial_coord[1] -= line_height continue offsets[:, :2] *= 1.5 strokes = drawing.offsets_to_coords(offsets) strokes = drawing.denoise(strokes) if denoise else strokes strokes[:, :2] = drawing.align(strokes[:, :2]) if align else strokes strokes[:, 1] *= -1 strokes[:, :2] -= strokes[:, :2].min() + initial_coord strokes[:, 0] += (view_width - strokes[:, 0].max()) / 2 prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*strokes.T): p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) prev_eos = eos path = svgwrite.path.Path(p) path = path.stroke(color="black", width=2, linecap='round').fill("none") dwg.add(path) initial_coord[1] -= line_height dwg.save()
def convert_gts_to_synth_format(stroke, adjustments=True): new_stroke = stroke[:, :3].copy() if np.any(new_stroke[:, -1] >= 2): #raise Exception("Input data is in stroke number format") warnings.warn("Input data is in stroke number format") new_stroke[:, -1] = stroke_recovery.relativefy(new_stroke[:, -1]) assert not np.any(new_stroke[:, -1] >= 2) # Round SOS new_stroke[:, -1] = np.round(new_stroke[:, -1]) #if np.all(new_stroke[0,:2] != 0): #new_stroke = np.concatenate([np.array([[0,0,0]]), new_stroke], axis=0) # Convert to EOS coords = sos_to_eos(new_stroke) if adjustments: coords = drawing.align(coords) coords = drawing.denoise(coords) offsets = drawing.coords_to_offsets(coords) offsets = offsets[:drawing.MAX_STROKE_LEN] offsets = drawing.normalize(offsets) return offsets
def _draw(self, strokes, lines, filename, stroke_colors=None, \ stroke_widths=None, background_color='white', \ png_convert=False): stroke_colors = stroke_colors or ['black'] * len(lines) stroke_widths = stroke_widths or [2] * len(lines) line_height = 8 view_height = 64 for offsets, line, color, width in zip(strokes, lines, stroke_colors, stroke_widths): # Dynamic width - consider at least 24px for each character view_width = len(line) * 24 # Minimum width is 192px if (view_width < 192): view_width = 192 # Create a file for each "line" dwg = svgwrite.Drawing(filename='./out/svg/%s.svg' % line) dwg.viewbox(width=view_width, height=view_height) dwg.add( dwg.rect(insert=(0, 0), size=(view_width, view_height), fill=background_color)) # Initial coordinates for the line height initial_coord = np.array([0, -(3 * line_height / 4)]) if not line: initial_coord[1] -= line_height continue print('Processing %s' % line) offsets[:, :2] *= 1.5 strokes = drawing.offsets_to_coords(offsets) strokes = drawing.denoise(strokes) strokes[:, :2] = drawing.align(strokes[:, :2]) strokes[:, 1] *= -1 strokes[:, :2] -= strokes[:, :2].min() + initial_coord strokes[:, 0] += (view_width - strokes[:, 0].max()) / 2 prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*strokes.T): p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) prev_eos = eos path = svgwrite.path.Path(p) path = path.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path) initial_coord[1] -= line_height # Save the svg dwg.save() # If PNGs are needed convert them if (png_convert): svg2png(open('./out/svg/%s.svg' % line, 'rb').read(), \ write_to=open('./out/png/%s.png' % line, 'wb')) # Finally create a file containing the dataset information with open('./out/dataset.txt', 'w') as f: for item in lines: f.write('./micra_dataset/%s.png %s\n' % (item, item))
def _draw(self, strokes, lines, filename, line_num,stroke_colors=None, stroke_widths=None): stroke_colors = stroke_colors or ['black']*len(lines) stroke_widths = stroke_widths or [2]*len(lines) line_height = 80 view_width = 500 view_height = line_height*(len(strokes) + 1) dwg = svgwrite.Drawing(filename='p1.svg') dwg.viewbox(width=view_width, height=view_height) dwg.add(dwg.rect(insert=(0, 0), size=(view_width, view_height), fill='white')) initial_coord = np.array([0, -(3*line_height / 4)]) for offsets, line, color, width in zip(strokes, lines, stroke_colors, stroke_widths): if not line: initial_coord[1] -= line_height continue offsets[:, :2] *= 1.2 strokes = drawing.offsets_to_coords(offsets) strokes = drawing.denoise(strokes) strokes[:, :2] = drawing.align(strokes[:, :2]) strokes[:, 1] *= -1 strokes[:, :2] -= strokes[:, :2].min() + initial_coord strokes[:, 0] += (view_width - strokes[:, 0].max()) / 2 prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*strokes.T): p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) prev_eos = eos path = svgwrite.path.Path(p) path = path.stroke(color=color, width=width, linecap='round').fill("none") #print(path) dwg.add(path) initial_coord[1] -= line_height dwg.save() with Image(filename='p1.svg', format='svg') as img: img.format='png' img.save(filename="s.png") img_small = cv2.imread("s.png") img_large = cv2.imread("templates/large1.jpg") #print(img_large.shape) #overlay_image_alpha(img_large, # img_small[:, :, :], # (0, 0), # img_small[:, :, :] / 255.0) s_img = cv2.imread("s.png",0) # print(s_img.shape) l_img = cv2.imread("large1.jpg",0) # print(l_img.shape) x_offset=100 y_offset=200 + (line_num) * 75 l_img[y_offset:y_offset+s_img.shape[0], x_offset:x_offset+s_img.shape[1]] = s_img outfile = "output/" + filename cv2.imwrite(outfile,l_img)
def _draw(self, strokes, lines, filename, line_num, stroke_colors=None, stroke_widths=None): stroke_colors = stroke_colors or ['black'] * 4 stroke_widths = stroke_widths or [2] * 4 i = 1 #i+=1 img_large = cv2.imread("templates/large1.jpg") l_img = cv2.imread("large1.jpg", 0) for offsets, line, color, width in zip(strokes, lines, stroke_colors, stroke_widths): svgfil = 'p' + str(i) + '.svg' if i == 1: line_height = 30 view_width = 200 dwg1 = svgwrite.Drawing(filename=svgfil) dwg = dwg1 if i == 2: line_height = 30 view_width = 300 dwg2 = svgwrite.Drawing(filename=svgfil) dwg = dwg2 if i == 3: line_height = 60 view_width = 450 dwg3 = svgwrite.Drawing(filename=svgfil) dwg = dwg3 if i == 4: line_height = 60 view_width = 450 dwg4 = svgwrite.Drawing(filename=svgfil) dwg = dwg4 #line_height = 50 #view_width = 300 view_height = line_height * 2 dwg.viewbox(width=view_width, height=view_height) dwg.add( dwg.rect(insert=(0, 0), size=(view_width, view_height), fill='white')) initial_coord = np.array([0, -(3 * line_height / 4)]) if not line: initial_coord[1] -= line_height continue offsets[:, :2] *= 1.1 strokes = drawing.offsets_to_coords(offsets) strokes = drawing.denoise(strokes) strokes[:, :2] = drawing.align(strokes[:, :2]) strokes[:, 1] *= -1 strokes[:, :2] -= strokes[:, :2].min() + initial_coord strokes[:, 0] += (view_width - strokes[:, 0].max()) / 2 prev_eos = 1.0 p = "M{},{} ".format(0, 0) for x, y, eos in zip(*strokes.T): p += '{}{},{} '.format('M' if prev_eos == 1.0 else 'L', x, y) prev_eos = eos if i == 1: path1 = svgwrite.path.Path(p) path1 = path1.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path1) if i == 2: path2 = svgwrite.path.Path(p) path2 = path2.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path2) if i == 3: path3 = svgwrite.path.Path(p) path3 = path3.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path3) if i == 4: path4 = svgwrite.path.Path(p) path4 = path4.stroke(color=color, width=width, linecap='round').fill("none") dwg.add(path4) #initial_coord[1] -= line_height dwg.save() with Image(filename=svgfil, format='svg') as img: img.format = 'png' img.save(filename="s.png") s_img = cv2.imread("s.png", 0) #control placement of text on the form if i == 1: x_offset = 135 y_offset = 50 if i == 2: x_offset = 155 y_offset = 110 if i == 3: x_offset = 150 y_offset = 300 if i == 4: x_offset = 150 y_offset = 390 l_img[y_offset:y_offset + s_img.shape[0], x_offset:x_offset + s_img.shape[1]] = s_img outfile = "output/" + filename i = i + 1 cv2.imwrite(outfile, l_img) s_img = np.ones(s_img.shape) * int(255) cv2.imwrite("s.png", s_img)