From 0d0fd3e638264dc812bd403898a70e2f87337331 Mon Sep 17 00:00:00 2001 From: iou1name Date: Wed, 21 Mar 2018 12:00:46 -0400 Subject: [PATCH] making it pretty --- draw.py | 2 +- linedraw.py | 204 +++++++++++++++++++++++++++------------------------- 2 files changed, 106 insertions(+), 100 deletions(-) diff --git a/draw.py b/draw.py index 106784a..7439e7d 100644 --- a/draw.py +++ b/draw.py @@ -5,8 +5,8 @@ machine chooch. """ import os -import linedraw import stream +import linedraw def draw(rec_filename): """ diff --git a/linedraw.py b/linedraw.py index 8cee331..9826357 100644 --- a/linedraw.py +++ b/linedraw.py @@ -1,11 +1,15 @@ +#!/usr/bin/env python3 +""" +Takes a raster image file and vectorizes it to create line art usable by +a pen plotter. +""" import os -from random import * import math +from random import * from PIL import Image, ImageDraw, ImageOps no_cv = True -export_path = "output/out.svg" draw_contours = True draw_hatch = False @@ -24,16 +28,18 @@ F_Blur = { (-2,1):4,(-1,1):9,(0,1):12,(1,1):9,(2,1):4, (-2,2):2,(-1,2):4,(0,2):5,(1,2):4,(2,2):2, } + F_SobelX = { (-1,-1): 1, (0,-1): 0, - (1,-1): -1, + (1,-1): -1, (-1,0): 2, (0,0): 0, - (1,0): -2, + (1,0): -2, (-1,1): 1, (0,1): 0, - (1,1): -1} + (1,1) -1} + F_SobelY = { (-1,-1): 1, (0,-1): 2, @@ -41,27 +47,27 @@ F_SobelY = { (-1,0): 0, (0,0): 0, (1,0): 0, - (-1,1): -1, - (0,1): -2, - (1,1): -1} + (-1,1): -1, + (0,1): -2, + (1,1): -1} -def appmask(IM,masks): - PX = IM.load() - w,h = IM.size +def appmask(image, masks): + PX = image.load() + w, h = image.size NPX = {} - for x in range(0,w): - for y in range(0,h): + for x in range(0, w): + for y in range(0, h): a = [0]*len(masks) for i in range(len(masks)): for p in masks[i].keys(): - if 0 128 and 255) + image = np.array(image) + image = cv2.GaussianBlur(image, (3, 3), 0) + #image = cv2.Canny(image,100,200) + image = auto_canny(image) + image = Image.fromarray(image) + return image.point(lambda p: p > 128 and 255) -def getdots(IM): +def getdots(image): print("getting contour points...") - PX = IM.load() + PX = image.load() dots = [] - w,h = IM.size + w, h = image.size for y in range(h-1): row = [] - for x in range(1,w): - if PX[x,y] == 255: + for x in range(1, w): + if PX[x, y] == 255: if len(row) > 0: - if x-row[-1][0] == row[-1][-1]+1: - row[-1] = (row[-1][0],row[-1][-1]+1) + if x-row[-1][0] == row[-1][-1] + 1: + row[-1] = (row[-1][0], row[-1][-1] + 1) else: - row.append((x,0)) + row.append((x, 0)) else: - row.append((x,0)) + row.append((x, 0)) dots.append(row) return dots @@ -150,110 +155,110 @@ def connectdots(dots): print("connecting contour points...") contours = [] for y in range(len(dots)): - for x,v in dots[y]: + for x, v in dots[y]: if v > -1: if y == 0: - contours.append([(x,y)]) + contours.append([(x, y)]) else: closest = -1 cdist = 100 - for x0,v0 in dots[y-1]: - if abs(x0-x) < cdist: - cdist = abs(x0-x) + for x0, v0 in dots[y-1]: + if abs(x0 - x) < cdist: + cdist = abs(x0 - x) closest = x0 if cdist > 3: - contours.append([(x,y)]) + contours.append([(x, y)]) else: found = 0 for i in range(len(contours)): - if contours[i][-1] == (closest,y-1): - contours[i].append((x,y,)) + if contours[i][-1] == (closest, y-1): + contours[i].append((x, y,)) found = 1 break if found == 0: - contours.append([(x,y)]) + contours.append([(x, y)]) for c in contours: - if c[-1][1] < y-1 and len(c)<4: + if c[-1][1] < y-1 and len(c) < 4: contours.remove(c) return contours -def getcontours(IM,sc=2): +def getcontours(image, sc=2): print("generating contours...") - IM = find_edges(IM) - IM1 = IM.copy() - IM2 = IM.rotate(-90,expand=True).transpose(Image.FLIP_LEFT_RIGHT) - dots1 = getdots(IM1) + image = find_edges(image) + image1 = IM.copy() + image2 = image.rotate(-90, expand=True).transpose(Image.FLIP_LEFT_RIGHT) + dots1 = getdots(image1) contours1 = connectdots(dots1) - dots2 = getdots(IM2) + dots2 = getdots(image2) contours2 = connectdots(dots2) for i in range(len(contours2)): - contours2[i] = [(c[1],c[0]) for c in contours2[i]] - contours = contours1+contours2 + contours2[i] = [(c[1], c[0]) for c in contours2[i]] + contours = contours1 + contours2 for i in range(len(contours)): for j in range(len(contours)): - if len(contours[i]) > 0 and len(contours[j])>0: - if distsum(contours[j][0],contours[i][-1]) < 8: - contours[i] = contours[i]+contours[j] + if len(contours[i]) > 0 and len(contours[j]) > 0: + if distsum(contours[j][0], contours[i][-1]) < 8: + contours[i] = contours[i] + contours[j] contours[j] = [] for i in range(len(contours)): - contours[i] = [contours[i][j] for j in range(0,len(contours[i]),8)] + contours[i] = [contours[i][j] for j in range(0, len(contours[i]), 8)] contours = [c for c in contours if len(c) > 1] - for i in range(0,len(contours)): - contours[i] = [(v[0]*sc,v[1]*sc) for v in contours[i]] + for i in range(0, len(contours)): + contours[i] = [(v[0] * sc, v[1] * sc) for v in contours[i]] - for i in range(0,len(contours)): - for j in range(0,len(contours[i])): - contours[i][j] = int(contours[i][j][0]+10),int(contours[i][j][1]+10) + for i in range(0, len(contours)): + for j in range(0, len(contours[i])): + contours[i][j] = int(contours[i][j][0] + 10), int(contours[i][j][1] + 10) return contours -def hatch(IM,sc=16): +def hatch(image, sc=16): print("hatching...") - PX = IM.load() - w,h = IM.size + PX = image.load() + w,h = image.size lg1 = [] lg2 = [] for x0 in range(w): for y0 in range(h): - x = x0*sc - y = y0*sc - if PX[x0,y0] > 144: + x = x0 * sc + y = y0 * sc + if PX[x0, y0] > 144: pass - elif PX[x0,y0] > 64: - lg1.append([(x,y+sc/4),(x+sc,y+sc/4)]) - elif PX[x0,y0] > 16: - lg1.append([(x,y+sc/4),(x+sc,y+sc/4)]) - lg2.append([(x+sc,y),(x,y+sc)]) + elif PX[x0, y0] > 64: + lg1.append([(x, y+sc/4), (x+sc, y+sc/4)]) + elif PX[x0, y0] > 16: + lg1.append([(x, y+sc/4), (x+sc, y+sc/4)]) + lg2.append([(x+sc, y), (x, y+sc)]) else: - lg1.append([(x,y+sc/4),(x+sc,y+sc/4)]) - lg1.append([(x,y+sc/2+sc/4),(x+sc,y+sc/2+sc/4)]) - lg2.append([(x+sc,y),(x,y+sc)]) + lg1.append([(x, y+sc/4), (x+sc, y+sc/4)]) + lg1.append([(x, y+sc/2 + sc/4), (x+sc, y+sc/2 + sc/4)]) + lg2.append([(x+sc, y), (x, y+sc)]) - lines = [lg1,lg2] - for k in range(0,len(lines)): - for i in range(0,len(lines[k])): - for j in range(0,len(lines[k])): + lines = [lg1, lg2] + for k in range(0, len(lines)): + for i in range(0, len(lines[k])): + for j in range(0, len(lines[k])): if lines[k][i] != [] and lines[k][j] != []: if lines[k][i][-1] == lines[k][j][0]: - lines[k][i] = lines[k][i]+lines[k][j][1:] + lines[k][i] = lines[k][i] + lines[k][j][1:] lines[k][j] = [] lines[k] = [l for l in lines[k] if len(l) > 0] - lines = lines[0]+lines[1] + lines = lines[0] + lines[1] - for i in range(0,len(lines)): - for j in range(0,len(lines[i])): - lines[i][j] = int(lines[i][j][0]+sc),int(lines[i][j][1]+sc)-j + for i in range(0, len(lines)): + for j in range(0, len(lines[i])): + lines[i][j] = int(lines[i][j][0] + sc), int(lines[i][j][1] + sc) - j return lines @@ -268,6 +273,7 @@ def sketch(path, export_path=None, resolution=1024, hatch_size=16, contour_simpl width = int(resolution/contour_simplify) height = int(resolution/contour_simplify*image.size[0]/image.size[1]) lines += getcontours(image.resize((width, height)), contour_simplify) + if draw_hatch: width = int(resolution/hatch_size) height = int(resolution/hatch_size*image.size[0]/image.size[1])