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
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
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
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()
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