def __init__(self, W=2970 // 3, H=2100 // 3): self.canvas = 255 * np.ones((H, W)) cv2.namedWindow('canvas') cv2.setMouseCallback('canvas', self.handler) self.down = False self.use_servo = True self.started = True self.tracking = False self.last_pos = None try: self.plotter = Plotter('/dev/ttyUSB0', 115200) self.plotter.load_config('config.json') self.plotter.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) except: print('no plotter connected') self.plotter = None
def run(args): # att = Clifford(-1.7, 1.3, -0.1, -1.21) # att = DequanLi(40, 1.833, 0.16, 0.65, 55, 20, # x=0.349, # y=0.0, # z=-0.16, # dt=0.0001) att = halvorsen(1.4, x=1, y=0, z=0, dt=0.0049) points = [] burn_in = 1000 [next(att) for _ in range(burn_in)] points = [next(att) for _ in range(750000)] points = np.array(points) # from mpl_toolkits.mplot3d import Axes3D # ax = plt.axes(projection="3d") # ax.plot3D(points[:, 0], # points[:, 1], # points[:, 2], # lw=0.01) # plt.figure() points = isometric(points.T).T y_margin_mm = 30 x_margin_mm = 30 H = 210 # A4 W = 297 # A4 points = resize_and_center(points, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) N_pre_simplification = points.shape[0] # points = simplify_reumann_witkam(0.07, points) N_post_simplification = points.shape[0] print('line simplified from {} to {} points ({}%)'.format( N_pre_simplification, N_post_simplification, int(np.round(100 * N_post_simplification / N_pre_simplification)))) plt.plot(points[:, 0], points[:, 1], '-', linewidth=0.02) plt.plot(points[0:500, 0], points[0:500, 1], 'r-') plt.plot(points[0, 0], points[0, 1], 'rx') plt.axis('equal') plt.show() with Plotter('/dev/ttyUSB0', 9600) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polyline(points, n_decimal=1) return 0
def run(args): particles = circle((0, 0), 1, N=360) forces = [] x_noise = OpenSimplex(42) y_noise = OpenSimplex(211) np.random.seed(64) dist = lambda x: np.linalg.norm(x) forces.append(lambda x: 0.6*np.array( [x_noise.noise2d(x=x[0], y=x[1]), y_noise.noise2d(x=x[0], y=x[1])])) forces.append(lambda x: 0.05*gravity(x, np.array((2, 2)))) forces.append(lambda x: 0.05*gravity(x, np.array((1.5, 0)))) forces.append(lambda x: 0.05*gravity(x, np.array((1.5, 1.5)))) forces.append(lambda x: -x if dist(x) > 3 else np.array((0.0, 0.0))) to_draw = [] for p in tqdm.tqdm(particles): path = run_particle(p, forces, N_steps=np.random.randint(999, 1000), step_size=1) to_draw.append(path) x_margin_mm = 30 y_margin_mm = 30 H = 210 # A4 W = 297 # A4 to_draw = resize_and_center(to_draw, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) simplified = [] for p in to_draw: simplified.append(simplify_reumann_witkam(0.5, p)) to_draw = optimize(simplified) vis_drawing(to_draw, 'b-', lw=0.1) plt.axis('equal') plt.gca().invert_yaxis() plt.show() # return 1 with Plotter('/dev/ttyUSB0', 9600) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(to_draw) return 0
def run(args): x_margin_mm = 20 y_margin_mm = 20 H = 210 # A4 W = 297 # A4 frac = 0.02 subdiv_step = 2.0 min_side = 1.0 triangle = np.array([[0, 0], [20, 0], [10, (np.sqrt(3) / 2) * 20], [0, 0] ]) * 10 triangle = resize_and_center([triangle], H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm)[0] to_draw = [triangle.copy()] i = 0 while i < 5000: side_lengths = np.array(triangle_lengths(triangle)) subdiv_frac = subdiv_step / side_lengths subdiv_frac[:] = frac if np.isnan(subdiv_frac[0]): break subdivision = subdivide_triangle(triangle, subdiv_frac[0], subdiv_frac[1], subdiv_frac[2]) center_tri = subdivision[3] triangle = center_tri.copy() to_draw.append(triangle.copy()) max_len = np.amax(side_lengths) if max_len < min_side: break i += 1 stats = drawing_stats(to_draw) print('stats: {}'.format(stats)) vis_drawing(to_draw, 'k-', lw=0.5) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:') plt.axis('equal') plt.gca().invert_yaxis() plt.show() with Plotter('/dev/ttyUSB0', 9600) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(to_draw) return 0
def run(args): y_margin_mm = 30 x_margin_mm = 30 H = 210 # A4 W = 297 # A4 grid_gap_mm = args.grid_gap_mm points = grid((x_margin_mm, y_margin_mm), (W - x_margin_mm, H - y_margin_mm), (grid_gap_mm, grid_gap_mm)) points = optimize(points) if args.rot != 0: points = rotate(points, args.rot) with Plotter('/dev/ttyUSB0', 115200) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(points) return 0
def run(args): svg_path = args.path parsed_paths, attributes, svg_attributes = svgpt.svg2paths( svg_path, return_svg_attributes=True) logger.info('SVG loaded') paths = [] for path in parsed_paths: if path.iscontinuous(): paths.append(path) else: for p in path.continuous_subpaths(): paths.append(p) np_paths = [] step = 1 for path_i, path in enumerate(tqdm.tqdm(paths, desc='paths')): np_path = [cplx_to_xy(path.start)] for part in path: if type(part) is svgpt.path.Line: start = cplx_to_xy(part.start) end = cplx_to_xy(part.end) if start != np_path[-1]: np_path.append(start) np_path.append(end) else: length = part.length() steps = int(np.round(length / step)) # steps = 20 if steps == 0: continue fraction_step = 1 / steps for i in range(steps + 1): try: pt = path.point(fraction_step * i) pt = cplx_to_xy(pt) np_path.append(pt) except Exception: pass np_paths.append(np.array(np_path)) logger.info('SVG converted') to_draw = np_paths if args.rotate: to_draw = rotate(to_draw) page_conf = load_page_conf(args.format) x_margin_mm = args.margins y_margin_mm = args.margins H = page_conf['H'] # 210 # A4 W = page_conf['W'] # 297 # A4 to_draw = resize_and_center(to_draw, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) orig = copy.deepcopy(to_draw) if args.border_crop: border = rounded_rect(drawing_bbox(to_draw), args.border_round) vis_drawing([border], 'b-', linewidth=0.5) logger.info("Masking drawing") to_draw = mask_drawing(to_draw, border) to_draw = multi_pass(to_draw, args.multipass) if not args.noopt: logger.info("Starting optimization") to_draw = optimize(to_draw, path_join_threshold=args.join, line_simplification_threshold=args.simplify, path_drop_threshold=args.drop) logger.info('plotting') vis_drawing(to_draw, 'r-', linewidth=0.5) vis_drawing(orig, 'k-', linewidth=0.5) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:') plt.axis('equal') # plt.gca().invert_yaxis() plt.show() with Plotter('/dev/ttyUSB0', 9600) as p: p.load_config(args.opconfig) p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.set_speed(289) p.draw_polylines(to_draw) return 0
def run(args): try: from OtterPlotter import Plotter except ImportError: from fake_plotter import FakePlotter as Plotter import matplotlib.pyplot as plt # polygon = np.array([[0, 0], [2, 1], [1, 1.5], [0.5, 1], [0, 2], [3, 1], [0, 0]]) # # hatching = polygon_hatch(polygon, 0.04, 45) # hatching = polygon_crosshatch(polygon, 0.04, 45) # vis_drawing([polygon] + hatching, 'b-', lw=0.5) x_margin_mm = 10 y_margin_mm = 10 H = 210 # A4 W = 297 # A4 min_hatch_dist = 0.05 max_hatch_dist = 4 min_subdivision_level = 2 max_subdivision_level = 6 triangle = np.array([[0, 0], [20, 0], [10, (np.sqrt(3) / 2) * 20], [0, 0] ]) * 10 triangle = resize_and_center([triangle], H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm)[0] from collections import deque from opensimplex import OpenSimplex subdiv_noise = OpenSimplex() subdiv_noise_mult = 0.01 hatch_noise = OpenSimplex(42) hatch_noise_mult = 0.01 hatch_dist_noise = OpenSimplex(1117) hatch_dist_noise_mult = 0.05 hatch_angle_noise = OpenSimplex(2111) hatch_angle_noise_mult = 0.01 q = deque() q.append((triangle, 0)) triangles = [] while len(q) > 0: tri, level = q.pop() tri_center = np.mean(tri[:-1, :], axis=0) rnd = subdiv_noise.noise2d(x=tri_center[0] * subdiv_noise_mult * level, y=tri_center[1] * subdiv_noise_mult * level) rnd = remap(rnd, -1, 1, 0, 1) if not level <= min_subdivision_level \ and (level >= max_subdivision_level or rnd < 0.4): triangles.append(tri) else: rnd = subdiv_noise.noise2d( x=tri_center[0] * subdiv_noise_mult * level, y=tri_center[1] * subdiv_noise_mult * level) rnd = remap(rnd, -1, 1, 0.3, 0.7) rnd2 = subdiv_noise.noise2d( x=tri_center[1] * subdiv_noise_mult * level, y=tri_center[0] * subdiv_noise_mult * level) rnd2 = remap(rnd2, -1, 1, 0.3, 0.7) rnd3 = subdiv_noise.noise2d( x=tri_center[0] * subdiv_noise_mult * level, y=tri_center[0] * subdiv_noise_mult * level) rnd3 = remap(rnd3, -1, 1, 0.3, 0.7) # rnd = 0.5 subdivision = subdivide_triangle(tri, rnd, rnd2, rnd3) for new_tri in subdivision: q.append((new_tri, level + 1)) triangles = [inset_triangle(tri, 0.7) for tri in triangles] hatchings = [] for tri in triangles: tri_c = np.mean(tri[:-1, :], axis=0) hatch_dist = remap( hatch_dist_noise.noise2d(x=tri_c[0] * hatch_dist_noise_mult, y=tri_c[1] * hatch_dist_noise_mult), -1, 1, min_hatch_dist, max_hatch_dist) # hatch_dist = min_hatch_dist hatch_angle = remap( hatch_angle_noise.noise2d(x=tri_c[0] * hatch_angle_noise_mult, y=tri_c[1] * hatch_angle_noise_mult), -1, 1, 0, 180) rnd = remap( hatch_noise.noise2d(x=tri_c[0] * hatch_noise_mult, y=tri_c[1] * hatch_noise_mult), -1, 1, 0, 1) if rnd < 1 / 3: hatching = polygon_hatch(tri, hatch_dist, hatch_angle) hatchings += hatching elif rnd < 2 / 3: hatching = polygon_crosshatch(tri, hatch_dist, hatch_angle) hatchings += hatching # to_draw = [] # backstroke = [] # triangle[:, 1] += 10 # for i in np.linspace(0, 1, 30): # backstroke.append(triangle[0] + i * (triangle[1] - triangle[0])) # backstroke = np.array(backstroke) # to_draw = [triangle[:2], backstroke[::-1]] to_draw = [triangle] + triangles + hatchings pre_optim_stats = drawing_stats(to_draw) print('pre_optim_stats: {}'.format(pre_optim_stats)) vis_drawing(to_draw, 'k-', lw=0.5) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:') plt.axis('equal') plt.gca().invert_yaxis() plt.show() to_draw = [] + optimize(triangles, verbose=False) + optimize(hatchings, verbose=False) optim_stats = drawing_stats(to_draw) print('optim_stats: {}'.format(optim_stats)) with Plotter('/dev/ttyUSB0', 9600) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(to_draw) return 0
def run(args): saver = ReproSaver() saver.seed() if args.img is not None: drawing_name = os.path.splitext(os.path.basename(args.img))[0] img = cv2.imread(args.img) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: drawing_name = 'tonal_map' orig_tonal_map = np.linspace(0, 1, num=256) gray = np.tile(255 * orig_tonal_map.reshape(1, orig_tonal_map.size), (40, 1)).astype(np.uint8) gray = resize_to_max(gray, 4000) logger.info("drawing_name: {}".format(drawing_name)) edges = cv2.Canny(gray, 60, 80) edge_distance = distance_transform_edt(255 - edges) # cv2.imshow("cv: edges", edges) # cv2.imshow("cv: edge_distance", edge_distance / np.amax(edge_distance)) # while True: # c = cv2.waitKey(0) # if c == ord('q'): # import sys # sys.exit(1) density = 1 - (gray.astype(np.float64) / 255) def stippling_density(density): return density**3 logger.info("stippling") with tmp_np_seed(42): stippling_fn = CachedComputation( os.path.join("cache", f"curly_tsp_stipple_{drawing_name}.pkl"), force=args.force)(ascencio2010stippling) points = stippling_fn(stippling_density(density), K=200, min_r=2, max_r=75) gui = Drawer(point_r=10) # gui.add_lines([points.copy()], 'g') gui.add_points([points.copy()], 'k') # gui.draw() logger.info("TSP-ing") tsp_fn = CachedComputation(os.path.join("cache", f"curly_tsp_{drawing_name}.pkl"), force=args.force)(concorde_tsp) tsp_pts = tsp_fn(points) if args.straight_test: logger.debug('Using straight line instead of TSP path') tsp_pts = np.array([[20, gray.shape[0] / 2], [gray.shape[1] - 20, gray.shape[0] / 2]]) gui = Drawer() gui.add_lines([tsp_pts], 'k') # gui.draw() logger.info("squiggling") squiggle_fn = CachedComputation(os.path.join( "cache", f"curly_tsp_squiggle_{drawing_name}.pkl"), force=args.force)(chiu2015tone_scribble) squiggle_fn = chiu2015tone_scribble if os.path.exists( 'curly_tsp_LUT.npy' ) and not args.tonal_map and not args.straight_test and not args.nolut: LUT = np.load('curly_tsp_LUT.npy') logger.info('using tonal mapping LUT') gray = apply_LUT(gray, LUT) speed_img = gray speed_img = speed_img.astype(np.float32) / 255 if args.tonal_map or args.straight_test: edge_distance = None to_draw = [ squiggle_fn(tsp_pts, r=185, speed_img=speed_img, edge_dist_img=edge_distance) ] gui = Drawer(lw=5) gui.add_lines(to_draw, (0, 0, 0, 1)) gui.draw() if args.tonal_map: rendered = render_lines(gray, to_draw[0]) sigma = 19 blurred_rendered = cv2.GaussianBlur(rendered, ksize=(0, 0), sigmaX=sigma) rendered_tonal_map = np.mean(blurred_rendered.astype(np.float32) / 255, axis=0) orig_tonal_map = gray[0, :].astype(np.float32) / 255 rendered_tones = np.tile(rendered_tonal_map[np.newaxis, :], (gray.shape[0], 1)) cv2.imshow("cv: rendered", rendered) cv2.imshow("cv: blurred rendered", blurred_rendered) cv2.imshow("cv: rendered_tones", rendered_tones) cv2.imshow("cv: gray", gray) while True: c = cv2.waitKey(0) if c == ord('q'): break cv2.destroyAllWindows() lut = compute_tonal_mapping(rendered_tonal_map, orig_tonal_map) np.save('curly_tsp_LUT', lut) if not args.nosave: saver.add_svg(to_draw) x_margin_mm = 5 y_margin_mm = 5 H = 210 # A4 W = 297 # A4 to_draw = rotate(to_draw) to_draw = resize_and_center(to_draw, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) border = [np.array([[0, 0], [W, 0], [W, H], [0, H], [0, 0]])] # gui = Drawer(point_r=2) # gui.add_lines(to_draw, 'b') # gui.add_lines(border, 'r') # gui.add_points(border, 'g') # gui.draw() # vis_drawing(to_draw, "r-", linewidth=0.5) if not args.noopt: to_draw = optimize(to_draw, line_simplification_threshold=0.1) vis_drawing(to_draw, "k-", linewidth=0.5) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], "k:") plt.axis("equal") plt.gca().invert_yaxis() plt.show() with Plotter() as p: p.load_config("config.json") p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(to_draw) return 0
def run(args): drawing = load_drawing(args.path) x_margin_mm = 10 y_margin_mm = 10 H = 210 # A4 W = 297 # A4 to_draw = resize_and_center(drawing, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) if type(to_draw) is not dict: # single layer to_draw = {'single_layer': to_draw} if not args.no_opt: to_draw = {layer_name: optimize(layer, line_simplification_threshold=args.simplify) for layer_name, layer in to_draw.items()} if 'black' in to_draw and 'red' in to_draw: vis_drawing(to_draw['black'], 'k-', lw=0.1) vis_drawing(to_draw['red'], 'r-', lw=0.3) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:') plt.axis('equal') plt.gca().invert_yaxis() plt.show() all_keys = set([str(i) for i in range(10)] + [chr(c) for c in range(97, 123)]) reserved_keys = set(['?', 'q']) layer_keys = sorted(list(all_keys - reserved_keys)) key_layer_mapping = {layer_keys[i]: layer_name for i, layer_name in enumerate(to_draw.keys())} def help(): print('? - this help') print('q - quit') for k in sorted(key_layer_mapping.keys()): print('{} - plot "{}" layer'.format(k, key_layer_mapping[k])) help() while True: key = getkey() print(key) if key == 'q': sys.exit(0) elif key == '?': help() elif key in key_layer_mapping: layer_name = key_layer_mapping[key] print('printing "{}"'.format(layer_name)) layer = to_draw[layer_name] with Plotter('/dev/ttyUSB0', 115200) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(layer) print('LAYER FINISHED') help() return 0
def run(args): img = cv2.imread(args.img) img = cv2.resize(img, (800, 600), cv2.INTER_AREA) ## create a flow field H, W = img.shape[:2] x_noise = OpenSimplex(240) y_noise = OpenSimplex(32) field = np.zeros((H, W, 2)) for y in range(H): for x in range(W): mult = 0.0015 x_val = x_noise.noise2d(x=mult * x, y=mult * y) y_val = y_noise.noise2d(x=mult * x, y=mult * y) field[y, x, :] = (x_val, y_val) # draw_field(field, N_particles=2000) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.float64) / 256 sigma = 3 gray = cv2.GaussianBlur(gray, ksize=(0, 0), sigmaX=sigma) # cv2.imshow("cv: gray", gray) # c = cv2.waitKey(0) # if c == ord('q'): # import sys # sys.exit(1) points = draw_field(field, guide=1 - gray, N_particles=10000) # ## draw the image with the flow field # cv2.namedWindow('cv: img', cv2.WINDOW_NORMAL) # cv2.imshow("cv: img", img) # # cv2.imshow("cv: field", np.linalg.norm(field, axis=2)) # cv2.imshow("cv: field", field[..., 0]) # cv2.resizeWindow('cv: img', 800, 600) # c = cv2.waitKey(0) # if c == ord('q'): # import sys # sys.exit(1) x_margin_mm = 10 y_margin_mm = 10 H = 210 # A4 W = 297 # A4 to_draw = resize_and_center(points, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) vis_drawing(to_draw, 'r-', linewidth=0.5) to_draw = optimize(to_draw, line_simplification_threshold=0.1) vis_drawing(to_draw, 'k-', linewidth=0.5) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:') plt.axis('equal') plt.gca().invert_yaxis() plt.show() H = 210 # A4 W = 297 # A4 with Plotter('/dev/ttyUSB0', 115200) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(to_draw) return 0
def run(args): N_per_layer = 8 N_per_blob = 21 N_layers = 12 r_min_layer = 5.5 r_layer_step = 1.6 N_per_circle = 30 r_circle_min = 0.05 r_circle_max = 1.1 paths = [] for i_layer in range(N_layers): r_layer = r_min_layer + i_layer * r_layer_step center_angles = np.linspace(0, 2 * np.pi, N_per_blob * N_per_layer, endpoint=False) # center_angles -= np.exp(remap(i_layer, 0, N_layers-1, # 0, 0.6)) # center_angles -= np.exp(i_layer*1.618 / N_layers) center_angles -= remap(i_layer, 0, N_layers - 1, 0, np.radians(120)) # center_angles += 1.618033 * i_layer for i_blob in range(N_per_layer): for i_circle in range(N_per_blob): center_x = r_layer * np.cos( center_angles[i_blob * N_per_blob + i_circle]) center_y = r_layer * np.sin( center_angles[i_blob * N_per_blob + i_circle]) # r_circle = remap(abs(i_circle - N_per_blob // 2), # 0, N_per_blob // 2, # r_circle_max, r_circle_min) r_circle = np.sin(remap(i_circle, 0, N_per_blob, 0, np.pi)) * r_circle_max + r_circle_min angle_start = np.random.rand() * 2 * np.pi angle_end = angle_start + 2 * np.pi angles = np.linspace(angle_start, angle_end, N_per_circle) sins = np.sin(angles) cosins = np.cos(angles) points = np.zeros((N_per_circle, 2)) points[:, 0] = cosins * r_circle + center_x points[:, 1] = sins * r_circle + center_y paths.append(points) # plt.axis('equal') # vis_drawing(paths, 'k-', linewidth=0.1) # plt.gca().invert_yaxis() # plt.show() x_margin_mm = 10 y_margin_mm = 10 H = 210 # A4 W = 297 # A4 to_draw = resize_and_center(paths, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) vis_drawing(to_draw, 'r-', linewidth=0.1) to_draw = optimize(to_draw, line_simplification_threshold=0.1) vis_drawing(to_draw, 'k-', linewidth=0.1) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:') plt.axis('equal') plt.gca().invert_yaxis() plt.show() H = 210 # A4 W = 297 # A4 # baud = 115200 baud = 9600 with Plotter('/dev/ttyUSB0', baud) as p: p.load_config('config.json') p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(to_draw) return 0
class GUI(): def __init__(self, W=2970 // 3, H=2100 // 3): self.canvas = 255 * np.ones((H, W)) cv2.namedWindow('canvas') cv2.setMouseCallback('canvas', self.handler) self.down = False self.use_servo = True self.started = True self.tracking = False self.last_pos = None try: self.plotter = Plotter('/dev/ttyUSB0', 115200) self.plotter.load_config('config.json') self.plotter.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) except: print('no plotter connected') self.plotter = None def handler(self, event, x, y, flags, param): if not self.started: return if self.last_pos is None: self.last_pos = (x, y) if event == cv2.EVENT_LBUTTONDOWN: self.down = True if (self.plotter is not None) and self.use_servo: self.plotter.goto(x, y, draw=False, skip_dupes=False) print('goto') self.plotter.pendown() self.last_pos = (x, y) print('down') elif event == cv2.EVENT_LBUTTONUP: self.down = False if (self.plotter is not None) and self.use_servo: self.plotter.penup() cv2.line(self.canvas, self.last_pos, (x, y), 0, 2) self.last_pos = (x, y) print('up') elif event == cv2.EVENT_MBUTTONDOWN: self.tracking = True elif event == cv2.EVENT_MBUTTONUP: self.tracking = False elif event == cv2.EVENT_MOUSEMOVE: # print(x, y) if self.down: cv2.line(self.canvas, self.last_pos, (x, y), 0, 2) if self.plotter is not None: if self.down or self.tracking: self.plotter.goto(x, y, draw=self.down, max_dupe_diff=max_dupe_diff) self.last_pos = (x, y) else: print(f"event: {event}") def loop(self): while True: cv2.imshow("canvas", self.canvas) c = cv2.waitKey(20) if c == ord('q'): break elif c == ord(' '): self.started = not self.started if self.plotter is not None: self.plotter.finalize()
def run(args): img = cv2.imread(args.img) img = resize_to_px_count(img, 1000**2) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur_type = 'bilateral' # blur_type = 'gauss' if blur_type == 'gauss': sigma = 8 if sigma > 0: gray = cv2.GaussianBlur(gray, ksize=(0, 0), sigmaX=sigma) elif blur_type == 'bilateral': sigmaColor = 20 sigmaSpace = 5 blurred = cv2.bilateralFilter(img, d=-1, sigmaColor=sigmaColor, sigmaSpace=sigmaSpace) # gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY) # sigma = 3 # gray = cv2.GaussianBlur(gray, ksize=(0, 0), sigmaX=sigma) # cv2.imshow("cv: gray", gray) # while True: # c = cv2.waitKey(0) # if c == ord('q'): # sys.exit(1) cmyk = bgr2cmyk(blurred) to_draw = {} N_hatches = args.N_hatches for i, name in enumerate("CMYK"): to_draw[name] = multi_hatch(cmyk[:, :, i], args.hatch_step_px, contour_tolerance=1, N_hatches=N_hatches, dark=False) to_draw[name] = [x[:, ::-1] for x in to_draw[name]] # swap x, y if args.rotate: to_draw = rotate(to_draw) page_conf = load_page_conf(args.format) x_margin_mm = args.margins y_margin_mm = args.margins H = page_conf['H'] # 210 # A4 W = page_conf['W'] # 297 # A4 # to_draw = rotate(to_draw) to_draw = resize_and_center(to_draw, H, W, x_margin_mm, x_margin_mm, y_margin_mm, y_margin_mm) border = rounded_rect(drawing_bbox(to_draw), 15) vis_drawing([border], 'b:', linewidth=0.5) to_draw = mask_drawing(to_draw, border) to_draw = optimize(to_draw, line_simplification_threshold=0.1, path_drop_threshold=2.0, path_join_threshold=1.0) vis_drawing(to_draw, layer_options={ 'C': (['c-'], dict(linewidth=0.1, alpha=0.5)), 'M': (['m-'], dict(linewidth=0.1, alpha=0.5)), 'Y': (['y-'], dict(linewidth=0.1, alpha=0.5)), 'K': (['k-'], dict(linewidth=0.1, alpha=0.5)), }) plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:') plt.show() with Plotter('/dev/ttyUSB0', 9600) as p: p.load_config(args.opconfig) p.set_input_limits((0, 0), (W, 0), (0, H), (W, H)) p.draw_polylines(to_draw) # cv2.imshow("cv: canvas", canvas) # while True: # c = cv2.waitKey(0) # if c == ord('q'): # break # plt.contour(gray, levels=levels, # colors='k', linewidths=0.1) # plt.axis('equal') # plt.gca().invert_yaxis() # plt.show() return 0