Example #1
0
    def generate(self):
        
        if not self.source:
            raise MissingSource("The spec '%s' has no source file associated"
                                " with it." % self)

        # TODO: Move into a generator base class
        # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.)
        try:
            img = open_image(self.source)
        except ValueError:

            # Re-open the file -- https://code.djangoproject.com/ticket/13750
            self.source.open()
            img = open_image(self.source)

        original_format = img.format       

        # Run the processors
        img = ProcessorPipeline(self.field.processors or []).process(img)

        #HOOK -- now process instance processors
        img = InstanceProcessorPipeline(self.field.instance_processors or []).process(img, self.instance)            

        format = self.field.format or img.format or original_format or 'JPEG'
        options = self.options or {}
        fobj = img_to_fobj(img, format, self.autoconvert, **options)
        # print 'fobj? %s - %s - %s'%(fobj, img, format)
        # print options
        return fobj
    def alg_change(self):
        algorithms = IntrinsicImagesAlgorithm.objects.filter(active=True) \
            .order_by('slug', '-id')
        algorithm_errors = {
            alg: [] for alg in algorithms
        }

        light_stacks = PhotoLightStack.objects.all()

        for alg in progress_bar(algorithms):
            use_alg = True
            for light_stack in light_stacks:
                photo_ids = light_stack.photos.values_list('id', flat=True)

                decompositions = IntrinsicImagesDecomposition.objects.filter(
                    algorithm=alg, photo_id__in=photo_ids)

                if len(decompositions) != len(photo_ids):
                    use_alg = False
                    break

                errors = []
                for d1 in decompositions:
                    r1 = open_image(d1.reflectance_image)
                    r1 = srgb_to_rgb(np.asarray(r1).astype(float) / 255.0)
                    r1 = np.mean(r1, axis=-1)

                    for d2 in decompositions:
                        if d1.photo_id == d2.photo_id:
                            continue
                        r2 = open_image(d2.reflectance_image)
                        r2 = srgb_to_rgb(np.asarray(r2).astype(float) / 255.0)
                        r2 = np.mean(r2, axis=-1)

                        errors.append(lmse(r1, r2))
                algorithm_errors[alg].append(np.mean(errors))

            if use_alg:
                print alg.slug, alg.id, \
                    np.mean(algorithm_errors[alg]), \
                    np.median(algorithm_errors[alg]), \
                    np.std(algorithm_errors[alg])

        errors = [
            (alg, np.mean(errors), np.median(errors), np.std(errors))
            for alg, errors in algorithm_errors.iteritems()
            if len(errors) == len(light_stacks)
        ]
        errors.sort(key=lambda x: x[1])

        for alg, e, m, s in errors:
            print alg.slug, alg.id, e, m, s
    def alg_change(self):
        algorithms = IntrinsicImagesAlgorithm.objects.filter(active=True) \
            .order_by('slug', '-id')
        algorithm_errors = {alg: [] for alg in algorithms}

        light_stacks = PhotoLightStack.objects.all()

        for alg in progress_bar(algorithms):
            use_alg = True
            for light_stack in light_stacks:
                photo_ids = light_stack.photos.values_list('id', flat=True)

                decompositions = IntrinsicImagesDecomposition.objects.filter(
                    algorithm=alg, photo_id__in=photo_ids)

                if len(decompositions) != len(photo_ids):
                    use_alg = False
                    break

                errors = []
                for d1 in decompositions:
                    r1 = open_image(d1.reflectance_image)
                    r1 = srgb_to_rgb(np.asarray(r1).astype(float) / 255.0)
                    r1 = np.mean(r1, axis=-1)

                    for d2 in decompositions:
                        if d1.photo_id == d2.photo_id:
                            continue
                        r2 = open_image(d2.reflectance_image)
                        r2 = srgb_to_rgb(np.asarray(r2).astype(float) / 255.0)
                        r2 = np.mean(r2, axis=-1)

                        errors.append(lmse(r1, r2))
                algorithm_errors[alg].append(np.mean(errors))

            if use_alg:
                print alg.slug, alg.id, \
                    np.mean(algorithm_errors[alg]), \
                    np.median(algorithm_errors[alg]), \
                    np.std(algorithm_errors[alg])

        errors = [(alg, np.mean(errors), np.median(errors), np.std(errors))
                  for alg, errors in algorithm_errors.iteritems()
                  if len(errors) == len(light_stacks)]
        errors.sort(key=lambda x: x[1])

        for alg, e, m, s in errors:
            print alg.slug, alg.id, e, m, s
def create_image_grid(items,
                      thumb_width=500,
                      thumb_height=500,
                      padding=0,
                      background=(255, 255, 255),
                      resize_to_fill=False):
    """ Greate a grid of images.

   :param items:  iterable of [(row, col, image), ...]
   """

    # adjust so that the top left is (0, 0)
    min_row = min(t[0] for t in items)
    min_col = min(t[1] for t in items)
    items = [(row - min_row, col - min_col, image)
             for (row, col, image) in items]

    # find bottom-right
    nrows = 1 + max(t[0] for t in items)
    ncols = 1 + max(t[1] for t in items)

    # output canvas
    cell_width = thumb_width + padding
    cell_height = thumb_height + padding
    size = (ncols * cell_width, nrows * cell_height)
    print 'Creating image grid...'
    print 'nrows:', nrows
    print 'ncols:', ncols
    print 'size:', size
    out = Image.new(mode='RGB', size=size, color=background)

    # splat images
    filled = np.zeros((nrows, ncols), dtype=np.bool)
    for (row, col, image) in items:
        if filled[row, col]:
            continue
        filled[row, col] = True

        try:
            if isinstance(image, basestring):
                thumb = Image.open(image)
            else:
                thumb = open_image(image)
        except Exception as e:
            print e
            continue

        if resize_to_fill:
            thumb = ResizeToFill(thumb_width, thumb_height).process(thumb)
        else:
            thumb = ResizeToFit(thumb_width, thumb_height).process(thumb)
            thumb = ResizeCanvas(thumb_width, thumb_height,
                                 color=background).process(thumb)

        x = col * cell_width
        y = row * cell_height
        out.paste(thumb, box=(x, y, x + thumb_width, y + thumb_height))

    return out
Example #5
0
def create_image_pair_grid_list(
        image_pairs, ncols=64, size=64, padding=0,
        show_progress=False, downsample_ratio=1):
    """ Greate a grid of images from a list of files """

    from pilkit.processors import ResizeToFit, ResizeCanvas

    nshapes = len(image_pairs)
    if downsample_ratio > 1:
        nshapes = (nshapes + downsample_ratio - 1) / downsample_ratio
        image_pairs = image_pairs[:nshapes]

    gridsize = size + padding
    nrows = (nshapes + ncols - 1) / ncols
    ncols = min(ncols, nshapes)
    out = Image.new(
        'RGBA', (ncols * gridsize, nrows * gridsize * 2),
        color=(255, 255, 255, 255))

    row = 0
    col = 0
    iterator = progress.bar(image_pairs) if show_progress else image_pairs
    for pair in iterator:
        for off, obj in enumerate(pair):
            try:
                thumb = open_image(obj)
            except Exception as e:
                print e
                continue
            thumb = ResizeToFit(size, size).process(thumb)
            thumb = ResizeCanvas(
                size, size, color=(255, 255, 255, 255)).process(thumb)
            out.paste(thumb, box=(
                col * gridsize,
                (2 * row + off) * gridsize,
                col * gridsize + size,
                (2 * row + off) * gridsize + size,
            ))
        col += 1
        if col >= ncols:
            col = 0
            row += 1

    # fix transparency (composite with pure opaque white)
    out.putdata([
        p if p[3] == 255
        else (
            (p[0] * p[3] + 255 * (255 - p[3])) / 255,
            (p[1] * p[3] + 255 * (255 - p[3])) / 255,
            (p[2] * p[3] + 255 * (255 - p[3])) / 255,
            255
        ) for p in out.getdata()
    ])

    return out
Example #6
0
def create_image_grid_qset(qset, image_attr, ncols=40, size=64, padding=0,
                           show_progress=False, downsample_ratio=1, max_qset_size=None):
    """ Greate a grid of images from a queryset """

    from pilkit.processors import ResizeToFit, ResizeCanvas

    # clamp number of shapes
    nshapes = qset.count()
    if downsample_ratio > 1:
        nshapes = (nshapes + downsample_ratio - 1) / downsample_ratio
    if max_qset_size:
        nshapes = min(nshapes, max_qset_size)
    qset = qset[:nshapes]

    gridsize = size + padding
    nrows = (nshapes + ncols - 1) / ncols
    ncols = min(ncols, nshapes)
    out = Image.new(
        'RGB', (ncols * gridsize, nrows * gridsize), color=0xffffff)

    row = 0
    col = 0
    iterator = queryset_progress_bar(qset) if show_progress else qset
    for obj in iterator:
        try:
            thumb = open_image(getattr(obj, image_attr))
        except Exception as e:
            print e
            continue
        thumb = ResizeToFit(size, size).process(thumb)
        thumb = ResizeCanvas(size, size, color=(255, 255, 255)).process(thumb)
        out.paste(thumb, box=(
            col * gridsize,
            row * gridsize,
            col * gridsize + size,
            row * gridsize + size,
        ))
        col += 1
        if col >= ncols:
            col = 0
            row += 1

    return out