def generatePoints(image): if (pointsGen == 'halftone'): depth = int(math.log(N,2)) #print(depth) dot_matrix = halftone.halftone(support.loadImageRGB(image), depth, halftone.renderDots) rows,cols = support.getSize(dot_matrix) dot_matrix = dot_matrix[1:rows-1,1:cols-1] rows,cols = support.getSize(dot_matrix) # Find points pointsList = [] for r in range(0,rows,1): for c in range(0,cols,1): if dot_matrix[r,c] == 0: pointsList.append([r,c]) # Find minimum distance for each point # Ceate new points list with minimum distance return generatePointTuples(pointsList, pointsList, rows, cols) elif (pointsGen == 'grid'): rows, cols = support.getSize(support.loadImageRGB(image)) size = math.sqrt(N) r_step = int(rows/size) r_init = r_step/2 c_step = int(cols/size) c_init = c_step/2 # Find points pointsList = [] for r in range (r_init, rows-1, r_step): for c in range(c_init, cols-1, c_step): pointsList.append([r,c]) # Find minimum distance for each point # Ceate new points list with minimum distance return generatePointTuples(pointsList, pointsList, rows, cols) elif (pointsGen == 'file'): f = file("points.txt", "w") line = f.readline().strip() pointsList = [] while line != "": values = line.split(" ") pointsList.append([int(values[0]), int(values[1])]) # Find minimum distance for each point # Ceate new points list with minimum distance return generatePointTuples(pointsList, pointsList, rows, cols) else: raise ValueError('Make sure pointsGen has a valid name')
def refineSuperPixels(imageLAB, superpixels): rowsIn, colsIn = support.getSize(imageLAB) N = len(superpixels) M = rowsIn * colsIn # Create dictionary of pixels where value is tuple of superpixel associated with # and difference to that superpixel pixels = {} # Figure out what pixels are associated with what superpixels border = int(2 * math.sqrt(float(M)/N)) for spName, sp in superpixels.iteritems(): sp.clear() out_r, out_c = sp.outPos in_r, in_c = sp.inPos # For every pixel in border for r in range(int(in_r-border),int(in_r+border+1),1): for c in range(int(in_c-border),int(in_c+border+1), 1): pixName = (r, c) # Boundary check if not utils.isOutOfBounds(rowsIn, colsIn, pixName): diff = sp.calcDiff(pixName, imageLAB, N, M) #Check if pixel is already in the dictionary if pixName in pixels: curDiff = pixels[pixName][1] if diff < curDiff: pixels[pixName] = (sp, diff) else: pixels[pixName] = (sp, diff) # Calculate superpixel averages for pos ,value in pixels.iteritems(): sp, diff = value sp.addPixel(imageLAB, pos)
def generatePoints(image): rows, cols = support.getSize(image) col_img = np.copy(image) image = support.rgb2gray(image * 255) # 1. Smooth the image with a Gaussian filter gauss = utils.makeKernel('gauss', gaus_r, gaus_sig) image = utils.smoothImage(image, gauss) # 2. Compute gradients using Sobel filter Kx, Ky = utils.makeKernel('sobel') Gx, Gy, G, D = utils.getEdges(image, Kx, Ky) Tr, Tc = updateGradients(Gx, Gy, G) step = r_strokew[0] init = step / 2 # Find points pointsList = [] r = init while r < rows - 1: c = init while c < cols - 1: pointsList.append([r, c]) c = c + step r = r + step random.shuffle(pointsList) return pointsList
def lineDrawing(image): # load image and create slightly smaller image due to gradients being smaller image_mat = support.loadImage(image) r, c = support.getSize(image_mat) image_mat = image_mat[1:r - 1, 1:c - 1] #print(image_mat[0:5,0:5]) #image_mat = image_mat / 255 #print(image_mat[0:5,0:5]) Kx, Ky = utils.makeKernel('sobel') Kx, Ky = normalizeMatrix(Kx), normalizeMatrix(Ky) Gx, Gy, G, D = utils.getEdges(image, Kx, Ky) Tx, Ty = gradientTangents(Gx, Gy) print(Tx[0:10, 0:10]) print(Ty[0:10, 0:10]) Tx_p, Ty_p = computeETF(Tx, Ty, G) print(Tx_p[0:10, 0:10]) print(Ty_p[0:10, 0:10]) print("Saving...") support.saveImage(Tx, "Tx_p_test") support.saveImage(Ty, "Ty__p_test") print("Saved") return computeFDoG(image_mat, Tx_p, Tx_p)
def updateGradients(Gr, Gc, G): if useFile: Tr = support.loadMatrix(Tr_file) Tc = support.loadMatrix(Tc_file) else: rows, cols = support.getSize(G) # 1. Compute the median of G and the max of G medVal_G = np.median(G) max_G = np.max(G) # 2. For each G[r,c] below a threshold*max for r in range(0, rows, 1): for c in range(0, cols, 1): val = G[r, c] if val < threshold * max_G: #compute unit vector from center to r,c v = normalizeVector( support.makeVector(r, c) - support.makeVector(int(rows / 2), int(cols / 2))) # scale vector by the median v = v * medVal_G # set Gr, Gc, G at (r,c to the components and magnitude of the vector) Gr[r, c] = v[0] Gc[r, c] = v[1] G[r, c] = math.sqrt(v[0] * v[0] + v[1] * v[1]) Tr, Tc = linedrawing.gradientTangents(Gr, Gc) if useEtf: Tr, Tc = linedrawing.computeETF(Tr, Tc, G) return Tr, Tc
def stipple(image): rows, cols = support.getSize(image) image = (image * -1) + 255 image = image / 255 avg_dist = 100 # large value to start points = generatePoints(image) P = computeP(image) Q = computeQ(P) while avg_dist > thresh: # create points.txt writePoints(points, rows, cols) edges = getVoroniEdges() lakes = generateLakes(points) avg_dist = computeCentroids(lakes, edges, P, Q, rows, cols) print "Average Distance", avg_dist points = [] for lake in lakes: points.append(lake.centroid) edgeList = [] for edge in edges: edgeList.append(edge.top) edgeList.append(edge.bot) resultCells = drawVoronoiCells(rows, cols, edgeList) return points, resultCells
def initSuperPixels(imageLAB, rowsOut, colsOut): rowsIn, colsIn = support.getSize(imageLAB) N = rowsOut * colsOut superpixels = {} r_step = rowsIn/rowsOut r_init = r_step/2 c_step = colsIn/colsOut c_init = c_step/2 cur_r = r_init cur_c = c_init # For each superpixel # Initialize outPos and inPos for out_r in range(0, rowsOut, 1): for out_c in range(0, colsOut, 1): name = "%d,%d" % (out_r, out_c) # ex. 4,3 for row 4 col 3 sp = SuperPixel(support.makeVector(out_r,out_c),\ support.makeVector(cur_r,cur_c), N) superpixels[name] = sp cur_c += c_step cur_r += r_step cur_c = c_init # Run SLIC refineSuperPixels(imageLAB, superpixels) return superpixels
def calcEndpoints(self): rows, cols = support.getSize(Tr) p = np.around(self.p) # Go forward x = p i = -1 cur_len = 0 while not isOutOfBounds(rows, cols, x) and i < self.length / 2: self.end1 = x x = x + self.getNewDir(x, self.thetap) i = i + 1 cur_len = cur_len + 1 # Go backwards x = p while not isOutOfBounds(rows, cols, x) and cur_len < self.length: self.end2 = x x = x - self.getNewDir(x, self.thetap) cur_len = cur_len + 1 # If we haven't reached stroke length yet continue in forward direction if cur_len != self.length: x = self.end1 while not isOutOfBounds(rows, cols, x) and cur_len < self.length: self.end1 = x x = x + self.getNewDir(x, self.thetap) cur_len = cur_len + 1 if cur_len != self.length: self.length = cur_len
def computeP(I): rows, cols = support.getSize(I) P = support.makeMatrix(rows, cols) P[0:rows, 0] = I[0:rows, 0] for r in range(0, rows, 1): for c in range(1, cols, 1): P[r, c] = I[r, c] + P[r, c - 1] return P
def pixelart(imageRGB, rowsOut, colsOut, K): rowsIn, colsIn = support.getSize(imageRGB) N = rowsOut * colsOut # Number of superpixels M = rowsIn * colsIn # Number of input pixels # Convert the input image to lab space imageLAB = support.rgb2lab(imageRGB) # Initialize superpixels, palette, and temperature superpixels = initSuperPixels(imageLAB, rowsOut, colsOut) palette = initPalette(imageLAB) T = initT(imageLAB) # While (T > Tf) i = 0 while T > Tf: if printProgress: print "Iteration: %d T: %d" % (i, T) # REFINE superpixels with 1 step of modified SLIC refineSuperPixels(imageLAB, superpixels) # ASSOCIATE superpixels to colors in the palette for cluster in palette: cluster.sub1.associate(superpixels, T, palette) cluster.sub2.associate(superpixels, T, palette) # REFINE colors in the palette totalChange = refinePalette(superpixels, palette) if printProgress: print "totalChange", totalChange # If (palette converged) print "Palette size: %d" % len(palette) if totalChange < ep_palette: # REDUCE temperature T = aT T = alpha * T # EXPAND palette expandPalette(palette, K) i += 1 # convert SuperPixels to matrix image result = support.makeVecMatrix(rowsOut * scale, colsOut * scale, 3) for sp in superpixels: r, c = int(sp.outPos[0]), int(sp.outPos[1]) result[r * scale:(r + 1) * scale, c * scale:(c + 1) * scale] = sp.ms # Post-process result[:, :, 1] = result[:, :, 1] * beta result[:, :, 2] = result[:, :, 2] * beta # Convert LAB image to RGB result = support.lab2rgb(result) return result
def generatePoints(image): rows, cols = support.getSize(image) if pointsGen == 'grid': size = math.sqrt(N) r_step = int(rows / size) r_init = r_step / 2 c_step = int(cols / size) c_init = c_step / 2 # Find points pointsList = [] for r in range(r_init, rows - 1, r_step): for c in range(c_init, cols - 1, c_step): pointsList.append([r, c]) return pointsList elif pointsGen == 'random': chosenPoints = {} while len(chosenPoints) < N: r = random.randint(10, rows - 10) c = random.randint(10, cols - 10) # if r,c is not already a chosen point value = (r, c) if value not in chosenPoints: chosenPoints[r, c] = support.makeVector(r, c) pointsList = [] for key, value in chosenPoints.iteritems(): pointsList.append(value) pointsList.sort(cmp=comparePoints) return pointsList elif pointsGen == 'file': matrix = support.loadMatrix(npy_file) rows, cols = support.getSize(matrix) pointsList = [] for r in range(0, rows, 1): value = matrix[r, 0] pointsList.append(value) return pointsList
def getTangentVector(Tx, Ty, z): rows, cols = support.getSize(Tx) T = support.makeVector(Tx[z[0], z[1]], Ty[z[0], z[1]]) T_tan = rotateCW(T) # round answers to integers Tx_tan = int(T_tan[0]) Ty_tan = int(T_tan[1]) return support.makeVector(Tx_tan, Ty_tan)
def computeQ(P): rows, cols = support.getSize(P) Q = support.makeMatrix(rows, cols) Q[0:rows, 1] = P[0:rows, 0] for r in range(0, rows, 1): for c in range(2, cols, 1): Q[r, c] = P[r, c - 1] + Q[r, c - 1] return Q
def convolve(image, kernel): image_matrix = support.loadImage(image) image_rows, image_cols = support.getSize(image_matrix) kernel_rows, kernel_cols = support.getSize(kernel) kernel_rows, kernel_cols = kernel_rows / 2, kernel_cols / 2 # A new matrix of zeros of final size of new image new_image = support.makeMatrix(image_rows, image_cols) # for each row in new image for r in range(kernel_rows, image_rows - kernel_rows, 1): # for each col in new image for c in range(kernel_cols, image_cols - kernel_cols, 1): # current matrix of image values conveq_matrix = image_matrix[r - kernel_rows:r + kernel_rows + 1, c - kernel_cols:c + kernel_cols + 1] # convolve image values and kernel new_image[r, c] = conveq(conveq_matrix, kernel) return new_image[kernel_rows:image_rows - kernel_rows, kernel_cols:image_cols - kernel_cols]
def computeField(strokesList, rows, cols): heightMap = support.loadImage(heightMap_f) / 255.0 opacityMap = support.loadImage(opacityMap_f) / 255.0 mapRows, mapCols = support.getSize(heightMap) heightField = support.makeMatrix(rows, cols, 0) colorField = support.makeVecMatrix(rows, cols, 3) # for each stroke print "Total = %d" % len(strokesList) for index, stroke in enumerate(strokesList): ## if index%20 == 0: ## os.system("pkill -f display") ## support.showImage( heightField ) if index % 100 == 0: print index samples = stroke.length # compute corner point r and coordinate system dirL = stroke.end2 - stroke.end1 dirW = rotateCW(dirL) dirL = impress.normalizeVector(dirL) dirW = impress.normalizeVector(dirW) r = stroke.end1 - dirW * (stroke.width / 2) # step sizes stepL = float(stroke.length) / samples stepW = float(stroke.width) / samples mapStepL = float(mapCols) / samples mapStepW = float(mapRows) / samples i = 0 while i < samples: j = 0 while j < samples: x = r + dirL * i * stepL + dirW * j * stepW if not impress.isOutOfBounds(rows, cols, x): f = impress.interpolate(x[0], x[1], heightField) map_c = i * mapStepL map_r = j * mapStepW h = impress.interpolate(map_r, map_c, heightMap) t = impress.interpolate(map_r, map_c, opacityMap) x = x.astype(int) heightField[x[0], x[1]] = f * (1 - t) + h * t heightField[x[0], x[1]] += fixedHeight colorField[x[0], x[1]] = colorField[x[0], x[1]] * ( 1 - t) + stroke.color * t j = j + 1 i = i + 1 heightField = normalizeMatrix(heightField) return heightField, colorField
def gradientTangents(Gx, Gy): rows, cols = support.getSize(Gx) zero_matrix = support.makeMatrix(rows, cols) Tx, Ty = zero_matrix, zero_matrix for r in range(0, rows, 1): for c in range(0, cols, 1): vec = support.makeVector(Gx[r, c], Gy[r, c]) tangent = rotateCCW(vec) Tx[r, c], Ty[r, c] = tangent[0], tangent[1] return Tx, Ty
def tessellate(image, pointsList, ETFr, ETFc): rows,cols = support.getSize(image) print("SIZE: %d x %d" % (rows,cols)) drawing = support.makeMatrix(rows,cols,-1) if curveType == 'ETF': growCurveETF(pointsList, drawing, ETFr, ETFc) print("Curve grown!") elif curveType == 'Lorentz': growCurveLorentz(pointsList,drawing) return assignColors(image,drawing)
def gradientTangents(Gx, Gy): rows, cols = support.getSize(Gx) Tx = support.makeMatrix(rows, cols) Ty = support.makeMatrix(rows, cols) for r in range(0, rows, 1): for c in range(0, cols, 1): vec = support.makeVector(Gx[r, c], Gy[r, c]) tangent = rotateCCW(vec) normaltangent = normalizeVector(tangent) Tx[r, c], Ty[r, c] = normaltangent[0], normaltangent[1] return Tx, Ty
def assignColors(image, drawing): #print "assign" rows, cols = support.getSize(drawing) rgbImage = support.makeVecMatrix(rows, cols, 3) for r in range(0, rows, 1): for c in range(0, cols, 1): if drawing[r, c] == -1: total, numPixels = computeColor(r, c, image, drawing) rgbColor = total / numPixels #print(rgbColor * 255) floodRegion(r, c, rgbColor, drawing, rgbImage) return rgbImage * 255
def generateStrokes(image): rows, cols = support.getSize(image) points = impress.generatePoints(image) strokes = [] for p in points: s = impress.stroke(p, image) s.calcEndpoints() strokes.append(s) return strokes
def draw(self, drawing, G, Tr, Tc): pix_map = drawing.load() draw = ImageDraw.Draw(drawing) rows, cols = support.getSize(G) p = np.around(self.p) # Go forward x = p x_prev = x i = -1 lastSample = 1000 while not isOutOfBounds(rows, cols, x) and i < self.length / 2: drawStroke(draw, x_prev * antialiased_sf, x * antialiased_sf, self.width, self.color) newSample = interpolate(x[0], x[1], G) if (clipping and newSample > lastSample): #print "clip" break x_prev = x if fixedOrientation: x = x + support.makeVector(-1, 1) #45 degrees else: x = x + getNewDir(Tr[x[0], x[1]], Tc[x[0], x[1]], self.thetap) lastSample = newSample i = i + 1 # Go backwards points = [] x = p x_prev = x i = 0 lastSample = 1000 while not isOutOfBounds(rows, cols, x) and i < self.length / 2: if not i == 0: drawStroke(draw, x_prev * antialiased_sf, x * antialiased_sf, self.width, self.color) newSample = interpolate(x[0], x[1], G) if (clipping and newSample > lastSample): #print "clip" break x_prev = x if fixedOrientation: x = x + support.makeVector(1, -1) #45 degrees else: x = x - getNewDir(Tr[x[0], x[1]], Tc[x[0], x[1]], self.thetap) lastSample = newSample i = i + 1
def sphereToRgb(r_mat, t_mat, p_mat): rows, cols = support.getSize(r_mat) x = r_mat * np.sin(t_mat) * np.cos(p_mat) y = r_mat * np.sin(t_mat) * np.sin(p_mat) z = r_mat * np.cos(t_mat) # load x, y, z into new matrix rgb_image = support.makeVecMatrix(rows, cols, 3) rgb_image[:, :, 0] = x rgb_image[:, :, 1] = y rgb_image[:, :, 2] = z return rgb_image
def __init__(self, r, c, ETFr, ETFc, direction): self.ETFr = ETFr self.ETFc = ETFc self.rows, self.cols = support.getSize(ETFr) self.F = support.makeVector(ETFr[r,c], ETFc[r,c]) if self.F[0] == 0 and self.F[1] == 0: self.F = getVectorCP(self.rows,self.cols,r,c) if direction == 'neg': self.F = -self.F self.v = support.makeVector(0,0) self.x = support.makeVector(r,c) self.prev_x = self.x self.a = self.F / m
def floodRegion(r, c, rgbColor, drawing, rgbImage): rows,cols = support.getSize(drawing) #base case # if draw_value != -2 # do nothing if not isOutOfBounds(rows,cols,r,c) and drawing[r,c] == -2: drawing[r,c] = -3 rgbImage[r,c] = rgbColor floodRegion(r-1,c,rgbColor,drawing,rgbImage) #north floodRegion(r+1,c,rgbColor,drawing,rgbImage) #south floodRegion(r,c-1,rgbColor,drawing,rgbImage) #east floodRegion(r,c+1,rgbColor,drawing,rgbImage) #west
def computeColor(r, c, image, drawing): #print"compute color" rows, cols = support.getSize(drawing) # base case: if isOutOfBounds(rows, cols, r, c) or drawing[r, c] != -1: return 0, 0 # otherwise drawing[r, c] = -2 n_tot, n_pix = computeColor(r - 1, c, image, drawing) s_tot, s_pix = computeColor(r + 1, c, image, drawing) e_tot, e_pix = computeColor(r, c - 1, image, drawing) w_tot, w_pix = computeColor(r, c + 1, image, drawing) total = image[r, c] + n_tot + s_tot + e_tot + w_tot numPixels = 1 + n_pix + s_pix + e_pix + w_pix return total, numPixels
def impress(image): color_img = np.copy(image) / 255 # Intesity image derived image = support.rgb2gray(image) ## rows, cols = support.getSize(image) ## for r in range(0, rows, 1): ## for c in range(0, cols, 1): ## image[r,c] = clamp(image[r,c] * random.uniform(r_sf[0],r_sf[1])) # 1. Smooth the image with a Gaussian filter gauss = utils.makeKernel('gauss', gaus_r, gaus_sig) image = utils.smoothImage(image, gauss) # 2. Compute gradients using Sobel filter Kx, Ky = utils.makeKernel('sobel') Gx, Gy, G, D = utils.getEdges(image, Kx, Ky) Tr, Tc = updateGradients(Gx, Gy, G) # Shrink image so that it matches convolution results r, c = support.getSize(image) image = image[1:r - 1, 1:c - 1] # 3. Generate a set of points on a grid to serve as the origins of the strokes points = generatePoints(r, c) # Create blank PIL image im = Image.new('RGB', (c * antialiased_sf, r * antialiased_sf)) # 4. For each origin, draw a stroke: i = 0 print len(points) for p in points: s = stroke(p, color_img) if i % 1000 == 0: print(i) i = i + 1 s.draw(im, G, Tr, Tc) im.thumbnail((c, r), Image.BICUBIC) return im
def convolve(image, kernel): image_matrix = support.loadImage(image) image_rows, image_cols = support.getSize(image_matrix) kernel_rows = support.getRows(kernel) new_image_rows = image_rows - kernel_rows new_image_cols = image_cols - kernel_rows # A new matrix of zeros of final size of new image new_image = support.makeMatrix(new_image_rows, new_image_cols) # for each row in new image for r in range(0, new_image_rows, 1): end_row = r + kernel_rows # for each col in new image for c in range(0, new_image_cols, 1): # current matrix of image values end_col = c + kernel_rows conveq_matrix = image_matrix[r:end_row, c:end_col] # convolve image values and kernel new_image[r, c] = conveq(conveq_matrix, kernel) return new_image
def inpaint(curImage, newImage, mask): rows, cols = support.getSize(mask) # For every vertex for i in range(0, rows, 1): mask_entry = mask[i, 0] r = int(mask_entry[0]) c = int(mask_entry[1]) t = mask_entry[2] O = curImage[r, c] E = curImage[r, c + 1] SE = curImage[r + 1, c + 1] S = curImage[r + 1, c] SW = curImage[r + 1, c - 1] W = curImage[r, c - 1] NW = curImage[r - 1, c - 1] N = curImage[r - 1, c] NE = curImage[r - 1, c + 1] # Get magnitudes of midpoints [Eq 6.15] mag_e = getMagnitude(O, E, NE, N, S, SE) mag_s = getMagnitude(O, S, SE, E, W, SW) mag_w = getMagnitude(O, W, SW, S, N, NW) mag_n = getMagnitude(O, N, NW, W, E, NE) neighbors = [E, S, W, N] weights = [wp(mag_e), wp(mag_s), wp(mag_w), wp(mag_n)] #[Eq 6.17/6.22] weightsum = sum(weights) lagr = lamb * (1 - t) hoo = lagr / (weightsum + lagr) #[Eq 6.19] # Calculate the hop sum [6.18] hop = [weight / (weightsum + lagr) for weight in weights] # Sum of hop times each vertex [Eq 6.20] hopup = 0 for h, v in zip(hop, neighbors): hopup += h * v newImage[r, c] = hopup + hoo * curImage[r, c] #[Eq 6.21]
def initSuperPixels(imageLAB, rowsOut, colsOut): rowsIn, colsIn = support.getSize(imageLAB) N = rowsOut * colsOut superpixels = [] r_step = rowsIn / rowsOut r_init = r_step / 2 c_step = colsIn / colsOut c_init = c_step / 2 cur_r = r_init cur_c = c_init # For each superpixel # Initialize outPos and inPos for out_r in range(0, rowsOut, 1): for out_c in range(0, colsOut, 1): sp = SuperPixel(support.makeVector(out_r,out_c),\ support.makeVector(cur_r,cur_c), N) superpixels.append(sp) cur_c += c_step cur_r += r_step cur_c = c_init # For each input pixel # Inialize what pixels are associated with what superpixels # Input pixels are assigned to the nearest superpixel in (x,y) space for r in range(0, rowsIn, 1): for c in range(0, colsIn, 1): pixPos = support.makeVector(r, c) minDist = 1000 #Initially a large number cur_sp = None for sp in superpixels: dist = utils.getVectorLength(pixPos - sp.inPos) if dist < minDist: minDist = dist cur_sp = sp cur_sp.addPixel(imageLAB, pixPos) return superpixels
def growCurveETF(pointsList, drawing, ETFr, ETFc): rows,cols = support.getSize(drawing) print rows, cols i = 1 allPoints = pointsList while len(pointsList) > 0: print("curve: %d"% i) i = i+1 point = findMaxDistPt(pointsList) pointsList.remove(point) # update minDist for points pointsList = generatePointTuples(pointsList, allPoints, rows, cols) r_init = point[0] c_init = point[1] curvePoints = [] # Draw Curve Positive curve = CurveETF(r_init,c_init, ETFr, ETFc, "pos") # while still drawing a curve isCurveDone = curve.drawCurveETF(curvePoints, drawing) while not isCurveDone: isCurveDone = curve.drawCurveETF(curvePoints, drawing) # Draw Curve Negative curve = CurveETF(r_init,c_init, ETFr, ETFc, "neg") # while still drawing a curve isCurveDone = curve.drawCurveETF(curvePoints, drawing) while not isCurveDone: isCurveDone = curve.drawCurveETF(curvePoints, drawing) """" if (len(curvePoints) < minLen): print "curve too small" # redraw points white for point in curvePoints: drawing[point[0], point[1]] = -1 else: """ allPoints.extend(curvePoints)