def nextPixelInShape(im, px): ''' Return a tuple which represents the next coordinate when proceeding clockwise around a shape. It is an implementation of the square tracing algorithm, which works as follows: if on a black square, turn left of previous direction and go forward if on a white square, turn right of previous direction and go forward Arguments: im is of type Image. Contains the image which is being processed. px is of type tuple. Contains float elements (x, y) which represent the current coordinate. ''' global direc, done pixels = im.load() try: pixel = pixel = sum(im.getpixel((px[0], px[1]))) except IndexError: pixel = sum((255, 255, 255)) # 0 = right, 1 = up, 2 = left, 3 = down if pixel < sum((127, 127, 127)): direc = (direc - 1) % 4 else: direc = (direc + 1) % 4 # Implementation of description in docstring if direc == 0: x = px[0] + 1 y = px[1] elif direc == 1: x = px[0] y = px[1] + 1 elif direc == 2: x = px[0] - 1 y = px[1] elif direc == 3: x = px[0] y = px[1] - 1 try: pixel = sum(im.getpixel((x, y))) except IndexError: pixel = sum((255, 255, 255)) # Since this function returns the next pixel, it can't return an off-shape # white pixel. It recurses until it finds a black pixel, which it returns. if pixel < sum((127, 127, 127)): if (x, y) not in done: done.append((x, y)) return (x, y) else: return nextPixelInShape(im, (x, y))
def readFromRaster(filename): ''' Return a list of sublists of tuples which correspond to (x, y) coordinates. Read the coordinates from a raster image, tracing the outline of each shape in the image. Arguments: filename is of type string. Contains name of image file. ''' global done # Create Image object from file in local folder im = initRaster(filename) # Find first point point = nextShape(im) start = point nextpoint = (0, 0) i = 0 shapeList = [] # While there are still shapes in the image while point != (-1, -1): start = point shapeList.append([]) shapeList[i].append(point) # While it has not yet fully traced around the image while nextpoint != start: nextpoint = nextPixelInShape(im, point) point = nextpoint done.append(point) shapeList[i].append(point) i += 1 point = nextShape(im) # Smooth coordinates in image shapeList = smoothRasterCoords(shapeList) # Ensure that each shape starts and ends on the same coordinate for i in range(len(shapeList)): if shapeList[i][-1] != shapeList[i][0]: shapeList[i].append(shapeList[i][0]) return shapeList
def nextShape(im): ''' Return a tuple which represents the leftmost point of the next shape. Arguments: im is of type Image. Contains the image which is being processed. ''' global IMDIM, done # Check the brightness of every point in the image for x in range(IMDIM): for y in range(IMDIM): # If a dark pixel is found that was not already read, return it if sum(im.getpixel((x, y))) < sum((127, 127, 127)) and\ isOnEdge(im, (x, y)) and not (x, y) in done: done.append((x, y)) return(x, y) # If no shape is found, return a special tuple return (-1, -1)