From 1a6fa82393309658eebc03875e2708b5633b6748 Mon Sep 17 00:00:00 2001 From: Ryan Bannon Date: Tue, 3 Jun 2014 14:08:07 -0400 Subject: [PATCH] Fixed #301: server now does polygon processing --- .../custom/pixel_segment/celery_task.py | 40 ++++++++++++++----- rodan/templates/jobs/pixel_segment.html | 4 -- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/rodan/jobs/gamera/custom/pixel_segment/celery_task.py b/rodan/jobs/gamera/custom/pixel_segment/celery_task.py index f41ad95e0..8f271c9c3 100644 --- a/rodan/jobs/gamera/custom/pixel_segment/celery_task.py +++ b/rodan/jobs/gamera/custom/pixel_segment/celery_task.py @@ -2,6 +2,7 @@ import sys from gamera.core import init_gamera, load_image from gamera.plugins.pil_io import from_pil +from PIL import ImageDraw from rodan.jobs.gamera.custom.gamera_custom_base import GameraCustomTask class PixelSegmentTask(GameraCustomTask): @@ -36,8 +37,7 @@ def process_image(self, task_image, settings): # For each of the geometries provided, we have to apply the pixel colour to non-white pixels. for geometry in geometries: - if self._is_rectangle(geometry['points']): - imageOriginal = self._apply_geometry(imageOriginal, geometry) + imageOriginal = self._apply_geometry(imageOriginal, geometry) # Convert red to white and black to green. colour_swap = {(255, 0, 0): (255, 255, 255), (0, 255, 0): (0, 0, 0)} @@ -80,6 +80,7 @@ def _apply_geometry(self, image, geometry): upperLeftY = sys.maxint lowerRightX = 0; lowerRightY = 0; + geometryTuples = [] for point in geometry['points']: point['x'] = int(point['x'] * scale) point['y'] = int(point['y'] * scale) @@ -87,23 +88,45 @@ def _apply_geometry(self, image, geometry): upperLeftY = point['y'] if point['y'] < upperLeftY else upperLeftY lowerRightX = point['x'] if point['x'] > lowerRightX else lowerRightX lowerRightY = point['y'] if point['y'] > lowerRightY else lowerRightY + geometryTuples.append((point['x'], point['y'])) box = (upperLeftX, upperLeftY, lowerRightX, lowerRightY) - # Change pixels and return. - image = self._colour_pixels(image, box, newColour) - return image + # Change pixels and return. If the geometry is a rectangle, we use a special + # method to speed things up that doesn't check for collision. + if self._is_rectangle(geometry['points']): + return self._colour_pixels(image, box, newColour, None) + else: + return self._colour_pixels(image, box, newColour, geometryTuples) # Colours all pixels in the image defined by the box the given colour (except white pixels). - def _colour_pixels(self, image, box, colour): + # If 'collisionGeometry' is provided, it will also check if the given pixel lies within + # the provided polygon. (So, if you have a rectangle, don't provided this...it can be null). + # + # NOTE: 'collisionGeometry' must be a list of tuples (e.g. [(x, y), (x, y), ...]) + def _colour_pixels(self, image, box, colour, collisionGeometry): # Crop out the image and get data. imageCrop = image.crop(box) imageCrop.load() imagePixelData = list(imageCrop.getdata()) + # If collisionGeometry is provided, we need to do collision detection. + imagePolygonPixelData = None + if collisionGeometry is not None: + imageCopy = image.copy() + draw = ImageDraw.Draw(imageCopy) + draw.polygon(collisionGeometry, (0, 0, 255), (0, 0, 255)) + del draw + imageCropPolygon = imageCopy.crop(box) + imageCropPolygon.load() + del imageCopy + imagePolygonPixelData = list(imageCropPolygon.getdata()) + del imageCropPolygon + # Go through pixels. for i in range(len(imagePixelData)): - if imagePixelData[i] != (255, 255, 255): + if imagePixelData[i] != (255, 255, 255) and \ + (collisionGeometry is None or imagePolygonPixelData[i] == (0, 0, 255)): imagePixelData[i] = colour # Apply and return. @@ -112,7 +135,7 @@ def _colour_pixels(self, image, box, colour): return image # Colours all pixels defined in "swap" keys with their "swap" values for the box dimensions. - # See '_colour_pixels'...very similar. + # See other '_colour_pixels_' methods...very similar. def _colour_swap_pixels(self, image, box, colour_swap): imageCrop = image.crop(box) imageCrop.load() @@ -125,4 +148,3 @@ def _colour_swap_pixels(self, image, box, colour_swap): return image - diff --git a/rodan/templates/jobs/pixel_segment.html b/rodan/templates/jobs/pixel_segment.html index 5116218b2..8fbdd7f6e 100644 --- a/rodan/templates/jobs/pixel_segment.html +++ b/rodan/templates/jobs/pixel_segment.html @@ -19,10 +19,6 @@ State - - Color - -