Ejemplo n.º 1
0
def evaluate_decomposition(decomposition_id,
                           delete_failed_open=False,
                           **evaluate_kwargs):
    """
    Evaluate a decomposition and return the fields to be updated on
    the IntrinsicImagesDecomposition instance.

    :param delete_failed_open: if ``True``, delete decompositions that generate
        an error upon opening.  Warning: if there is an internet problem,
        enabling this will cause otherwise valid decompositions to be deleted.
    """

    from intrinsic.evaluation import evaluate_error

    # fetch reflectance image
    decomp = None
    try:
        decomp = IntrinsicImagesDecomposition.objects.get(id=decomposition_id)
        reflectance_image = open_image(decomp.reflectance_image)
    except KeyboardInterrupt:
        return
    except Exception as e:
        print e
        if delete_failed_open:
            print "Deleting: id %s (algorithm: %s %s)" % tuple(
                IntrinsicImagesDecomposition.objects.filter(
                    id=decomposition_id).values_list('id', 'algorithm__slug',
                                                     'algorithm_id').get())
            IntrinsicImagesDecomposition.objects.filter(
                id=decomposition_id).delete()

        return {k: None for k in IntrinsicImagesDecomposition.ERROR_ATTRS}

    # evaluate score
    update_kwargs = evaluate_error(decomp.photo_id, reflectance_image,
                                   **evaluate_kwargs)
    return update_kwargs
Ejemplo n.º 2
0
def evaluate_decomposition(
        decomposition_id, delete_failed_open=False, **evaluate_kwargs):
    """
    Evaluate a decomposition and return the fields to be updated on
    the IntrinsicImagesDecomposition instance.

    :param delete_failed_open: if ``True``, delete decompositions that generate
        an error upon opening.  Warning: if there is an internet problem,
        enabling this will cause otherwise valid decompositions to be deleted.
    """

    from intrinsic.evaluation import evaluate_error

    # fetch reflectance image
    decomp = None
    try:
        decomp = IntrinsicImagesDecomposition.objects.get(id=decomposition_id)
        reflectance_image = open_image(decomp.reflectance_image)
    except KeyboardInterrupt:
        return
    except Exception as e:
        print e
        if delete_failed_open:
            print "Deleting: id %s (algorithm: %s %s)" % tuple(
                IntrinsicImagesDecomposition.objects
                .filter(id=decomposition_id).values_list('id', 'algorithm__slug', 'algorithm_id').get()
            )
            IntrinsicImagesDecomposition.objects.filter(id=decomposition_id).delete()

        return {
            k: None for k in IntrinsicImagesDecomposition.ERROR_ATTRS
        }

    # evaluate score
    update_kwargs = evaluate_error(decomp.photo_id, reflectance_image, **evaluate_kwargs)
    return update_kwargs
Ejemplo n.º 3
0
def _run_algorithm(photo, function, slug, parameters={},
                   image_size=512, baseline=False):
    """ Sets up an algorithm in the database, calls ``function``, then stores
    the result in the database """

    if not isinstance(photo, Photo):
        time_start = timeit.default_timer()
        r, s = function(image=photo, **parameters)
        time_end = timeit.default_timer()
        runtime = time_end - time_start
        r, s = [process_layer(x) for x in (r, s)]
        return r, s, runtime

    # ensure a consistent order for parameters
    algorithm, _ = IntrinsicImagesAlgorithm.objects.get_or_create(
        slug=slug, parameters=json.dumps(parameters, sort_keys=True), baseline=baseline)

    if IntrinsicImagesDecomposition.objects.filter(
            photo=photo, algorithm=algorithm).exists():
        print '_run_algorithm: EXISTS: photo %s, algorithm %s, params %s' % (
            photo.id, slug, parameters)
        return
    else:
        print '_run_algorithm: starting: photo %s, algorithm %s, params %s' % (
            photo.id, slug, parameters)

    # load and resize image (do it here rather than load the pre-resized photo
    # thumbnail to avoid jpg artifacts)
    attr = '_intrinsic_algorithm_photo_%s' % image_size
    if hasattr(photo, attr):
        image = getattr(photo, attr)
    else:
        image = photo.open_image(width='orig')
        image = ResizeToFit(image_size, image_size).process(image)
        setattr(photo, attr, image)

    time_start = timeit.default_timer()
    # r, s: linar numpy arrays
    r, s = function(image=image, **parameters)
    time_end = timeit.default_timer()
    runtime = time_end - time_start

    # r, s: sRGB numpy arrays
    r, s = [process_layer(x) for x in (r, s)]

    # r, s: sRGB PIL images
    reflectance_image = numpy_to_pil(r)
    shading_image = numpy_to_pil(s)

    # save in database
    with transaction.atomic():
        decomposition, _ = IntrinsicImagesDecomposition.objects \
            .get_or_create(photo=photo, algorithm=algorithm)

        # fill in fields
        decomposition.runtime = runtime
        save_obj_attr_image(
            decomposition, attr='reflectance_image',
            img=reflectance_image, format='png', save=False)
        save_obj_attr_image(
            decomposition, attr='shading_image',
            img=shading_image, format='png', save=False)

        # comupte error
        from intrinsic.evaluation import evaluate_error
        update_kwargs = evaluate_error(photo.id, reflectance_image)
        for k, v in update_kwargs.iteritems():
            setattr(decomposition, k, v)

        # save to database
        decomposition.save()

    print '_run_algorithm: DONE: photo %s, algorithm %s, params %s, runtime: %s' % (
        photo.id, slug, parameters, runtime)

    return r, s, runtime
Ejemplo n.º 4
0
def intrinsic_decomposition_task(photo_id, algorithm_id, task_version=0):
    """
    Decompose an image with a given algorithm and set of parameters.  The image
    is resized to fit in a 512 by 512 box.  The resize operation happens in the
    file's storage colorspace (likely sRGB).

    :param photo_id: ``photo.id``

    :param algorithm_id: ``algorithm.id``
    """

    #algorithm, _ = IntrinsicImagesAlgorithm.objects.get_or_create(
    #slug=algorithm_slug, parameters=json.dumps(parameters, sort_keys=True),
    #baseline=algorithm_slug.startswith('baseline_'))

    algorithm = IntrinsicImagesAlgorithm.objects.get(id=algorithm_id)
    parameters = json.loads(algorithm.parameters)

    if task_version != algorithm.task_version:
        print "Version changed (%s --> %s): exiting" % (task_version,
                                                        algorithm.task_version)
        return
    elif not algorithm.active:
        print "Algorithm not active: %s %s: exiting" % (algorithm.slug,
                                                        algorithm.parameters)
        return
    elif IntrinsicImagesDecomposition.objects.filter(
            photo_id=photo_id, algorithm=algorithm).exists():
        print "Already decomposed: photo_id: %s, algorithm: %s %s: exiting" % (
            photo_id, algorithm.slug, algorithm.parameters)
        return

    print 'intrinsic_decomposition_task: photo_id: %s, slug: %s, parameters: %s' % (
        photo_id, algorithm.slug, parameters)

    # download image
    photo = Photo.objects.get(id=photo_id)
    image = ResizeToFit(512, 512).process(photo.open_image(width='orig'))

    # decompose
    import intrinsic.algorithm
    func = getattr(intrinsic.algorithm, algorithm.slug)
    r, s, runtime = func(image, **parameters)
    r = numpy_to_pil(r)
    s = numpy_to_pil(s)

    # save: use atomic so that if the image save fails, the record is not kept
    with transaction.atomic():
        decomposition, _ = IntrinsicImagesDecomposition.objects \
            .get_or_create(photo_id=photo_id, algorithm=algorithm)

        decomposition.runtime = runtime
        save_obj_attr_image(decomposition,
                            attr='reflectance_image',
                            img=r,
                            format='png',
                            save=False)
        save_obj_attr_image(decomposition,
                            attr='shading_image',
                            img=s,
                            format='png',
                            save=False)

        from intrinsic.evaluation import evaluate_error
        update_kwargs = evaluate_error(photo_id, r)
        for k, v in update_kwargs.iteritems():
            setattr(decomposition, k, v)

        decomposition.save()
Ejemplo n.º 5
0
def _run_algorithm(photo,
                   function,
                   slug,
                   parameters={},
                   image_size=512,
                   baseline=False):
    """ Sets up an algorithm in the database, calls ``function``, then stores
    the result in the database """

    if not isinstance(photo, Photo):
        time_start = timeit.default_timer()
        r, s = function(image=photo, **parameters)
        time_end = timeit.default_timer()
        runtime = time_end - time_start
        r, s = [process_layer(x) for x in (r, s)]
        return r, s, runtime

    # ensure a consistent order for parameters
    algorithm, _ = IntrinsicImagesAlgorithm.objects.get_or_create(
        slug=slug,
        parameters=json.dumps(parameters, sort_keys=True),
        baseline=baseline)

    if IntrinsicImagesDecomposition.objects.filter(
            photo=photo, algorithm=algorithm).exists():
        print '_run_algorithm: EXISTS: photo %s, algorithm %s, params %s' % (
            photo.id, slug, parameters)
        return
    else:
        print '_run_algorithm: starting: photo %s, algorithm %s, params %s' % (
            photo.id, slug, parameters)

    # load and resize image (do it here rather than load the pre-resized photo
    # thumbnail to avoid jpg artifacts)
    attr = '_intrinsic_algorithm_photo_%s' % image_size
    if hasattr(photo, attr):
        image = getattr(photo, attr)
    else:
        image = photo.open_image(width='orig')
        image = ResizeToFit(image_size, image_size).process(image)
        setattr(photo, attr, image)

    time_start = timeit.default_timer()
    # r, s: linar numpy arrays
    r, s = function(image=image, **parameters)
    time_end = timeit.default_timer()
    runtime = time_end - time_start

    # r, s: sRGB numpy arrays
    r, s = [process_layer(x) for x in (r, s)]

    # r, s: sRGB PIL images
    reflectance_image = numpy_to_pil(r)
    shading_image = numpy_to_pil(s)

    # save in database
    with transaction.atomic():
        decomposition, _ = IntrinsicImagesDecomposition.objects \
            .get_or_create(photo=photo, algorithm=algorithm)

        # fill in fields
        decomposition.runtime = runtime
        save_obj_attr_image(decomposition,
                            attr='reflectance_image',
                            img=reflectance_image,
                            format='png',
                            save=False)
        save_obj_attr_image(decomposition,
                            attr='shading_image',
                            img=shading_image,
                            format='png',
                            save=False)

        # comupte error
        from intrinsic.evaluation import evaluate_error
        update_kwargs = evaluate_error(photo.id, reflectance_image)
        for k, v in update_kwargs.iteritems():
            setattr(decomposition, k, v)

        # save to database
        decomposition.save()

    print '_run_algorithm: DONE: photo %s, algorithm %s, params %s, runtime: %s' % (
        photo.id, slug, parameters, runtime)

    return r, s, runtime