def create_shape_image_sample(shape, sample_width=256, sample_height=256): """ Return a centered image sample of the shape, or None if a centered box intersects the shape edge """ from shapes.models import ShapeImageSample from common.wavelets import compute_wavelet_feature_vector if ShapeImageSample.objects.filter(shape=shape).exists(): return image = open_image(shape.photo.image_2048) image_width, image_height = image.size triangles = parse_triangles(shape.triangles) vertices = [(x * image_width, y * image_height) for (x, y) in parse_vertices(shape.vertices)] b = bbox_vertices(vertices) # make sure box is big enough if b[2] - b[0] < sample_width or b[3] - b[1] < sample_height: return None # try random boxes filled = False for iters in xrange(1000): x = int(random.uniform(b[0] + sample_width / 2, b[2] - sample_width / 2)) y = int(random.uniform(b[1] + sample_height / 2, b[3] - sample_height / 2)) box = (x - sample_width / 2, y - sample_height / 2, x + sample_width / 2, y + sample_height / 2) box = [int(f) for f in box] # make sure box is filled entirely poly = Image.new(mode='1', size=(box[2] - box[0], box[3] - box[1]), color=0) draw = ImageDraw.Draw(poly) vertices_shifted = [(x - box[0], y - box[1]) for (x, y) in vertices] for tri in triangles: points = [vertices_shifted[tri[t]] for t in (0, 1, 2)] draw.polygon(points, fill=1) del draw filled = True for p in poly.getdata(): if p != 1: filled = False break if filled: break if not filled: return None # create sample sample, created = ShapeImageSample.objects.get_or_create( shape=shape, defaults={'bbox': json.dumps(box)}) if created: sample_image = image.crop(box) sample.feature_vector = \ compute_wavelet_feature_vector(sample_image) save_obj_attr_image( sample, attr='image', img=sample_image, format='jpg', save=True) return sample
def compute_features(wavelet, img): return compute_wavelet_feature_vector(Image.open(img), wavelet=wavelet)