CSCI 476/576 Grad Project 1: Local Laplacian Filtering

Scott Wehrwein

Winter 2024

Assigned: Thursday, January 18, 2024

Deadline: Saturday, Feburary 10th, 2024 at 10pm

This project is to be done in pairs. Please use the Github Classroom link on Canvas. Name your team with the two usernames of your group members, sorted lexicographically. For example, if Brian Hutchinson and I were working on this together, our team would be hutchib2_wehrwes.

Overview

Laplacian pyramid editing (as in Proejct 1) goes a long way towards enabling detail enhancement in images, but it has some limitations. One of the most important of these is that gradients at the same spatial scale can represent detail or edges. If we want to amplify or attenuate details (e.g., texture) without, boosting or smoothing edges, we need to find a way to differentiate between the two and treat them differently.

One approach that accomplishes this by building on the Laplacian pyramid machinery we’ve is called Local Laplacian Filters. Rather than explaining them in detail here, I refer you to a few resources:

Task

Your task is to implement the fast variant of the Local Laplacian Filtering technique described in the 2014 TOG paper [3] above.

Disclaimer

Yep, this is probably difficult, and likely underspecified. I’ve given you relatively little guidance and lots of time, so please chip away at this gradually and come to me with questions.

Simplifications

To keep things (less un)manageable, you may make some simplifications:

Guidelines

Your implementation can (likely should) build on the Project 1 codebase, since you’ll already have the ability to construct and reconstruct Laplacian pyramids. I’ve set it up as a separate Github Classroom assignment, because this one is done in pairs whereas P1 is done individually. Both partners should be (substantially) done with P1 before you start coding up this one; at that point, you can import one group member’s P1 code into your G1 repository as a starting point. Note that you will probably spend plenty of time digesting the papers before you get down to coding, so this does not mean you should leave this project alone entirely until after P1 is due.

Beyond the P1 codebase, here is a GUI file, modeled after the pyramid editing GUI, that I made to visualize local Laplacian filtering results. To make this work, you’ll need to add a couple functions to filtering.py. Here are the function headers and specs that should interact correctly with the GUI code:

def construct_gaussian(img, levels):
    """ Construct a Gaussian pyramid for the image img with `levels` levels.
    Returns a python list of length `levels`, with level 0 being the input
    image, and each one thereafter being half the size of the level before it
    Precondition: img has dimensions HxWxC, and H and W are each divisible
    by 2**(levels-1) """
    # implementation here
   
def fast_llf(gpyr, sigma, alpha, beta, samples=10):
    """ Run a fast local laplacian filtering operation on the image represented
    by its grayscale Gaussian pyramid (gpyr). Input image values range between
    0 and 1. The edge/detail threshold is sigma, the local contrast exponent is
    alpha, and the edge attenuation coefficient is beta. This method uses the
    "fast" algorithm by precomputing a number (samples) of pyramids using
    sampled intensities and interpolating between them. Returns the final
    filtered grayscale image. """
    # implementation here; helper functions highly encouraged

I recommend spending some time getting a feel for the remapping function. Personally, I made (and have since lost 😢 - maybe someone could recreate it and share?) a Desmos plot showing the 1D tone curve with sliders that control \(\alpha\) and \(\beta\).

Report and Submission

To submit, please (1) push your code to your G1 repository and submit a report to Canvas in PDF or HTML format. The report should include:

  1. Names of group members

  2. Code guide

  3. Results

  4. Retrospective

    Tell me about how this project went. What did you find most interesting? Helpful? Challenging? What, if anything, could I change to minimize unnecessary suffering?