HDR merging

In this assignment, we will only work with images that are linear, static, and where the camera hasn't moved. The image files are provided with gamma 2.2 encoding and we have inserted lines of code in makeHDR and toneMap to decode and recode, respectively, the images. Keep these lines in your implementations of makeHDR and toneMap.

Consult the course slides for the overall merging approach. We will first compute weights for each pixel and each channel to eliminate values that are too high and too low. We will then compute the scale factor between the values of two images. Finally, we will merge a sequence of images using a weighted combination of the individual images according to the weights and scale factors.

Weights

Use testComputeWeight in a5_main.cpp to help test this function.

Factor

Now that we know which pixels are usable in each picture, we can compute the multiplication factor between a pair of images.

Use testComputeFactor in a5_main.cpp to help test this function.

w1
w2
(a) w1
(b) w2

Merge to HDR

Use the previous functions to merge a sequence of images. You can assume that the first one is the darkest one, and that they are given in order of increasing exposure.

Use testMakeHDR in a5_main.cpp to help test this function.

Tone mapping

Now that you have assembled HDR images, you are going to implement tone mapping. Your tone mapper will follow the method studied in class. The function will be called FloatImage toneMap(const Image &im, float targetBase, float detailAmp, bool useBila, float sigmaRange). It takes as input an HDR image, a target contrast for the base, an amplification factor for the detail, and a Boolean for the use of the bilateral filter vs. Gaussian blur.

As described in lecture slides, our goal is to reduce the contrast from the HDR image (say, 1:10000) to what we can show on a display (say 1:100). Although gamma correction would be the first thing we can think of, this results in washed out images, as you might have seen in class. The colors are actually okay (they're all there) but the high frequencies are washed out. We therefore want to work in the luminance, and increase the high frequencies, and we want to work in the log domain, since we are very sensitive to multiplicative contrast.

Next, we want to extract the detail of the (log) luminance channel. We do this by blurring the log luminance, and subtracting the original. Convince yourself that gives you the details (high frequencies)!

Great, you are finally ready to put everything together!

Enjoy your results and compare the bilateral version with the Gaussian one. Use the functions testToneMapping_ante2, testToneMapping_ante3, testToneMapping_design, testToneMapping_boston in a5_main.cpp to help test your tone mapping function.

gaussian tone mapping
bilaterial tone mapping
(a) Gaussian Tone Mapping
(b) Bilaterial Tone Mapping
gaussian tone mapping
bilaterial tone mapping
(a) Gaussian Tone Mapping
(b) Bilaterial Tone Mapping

Your own HDR photo.

Extra credit

Here are some ideas for extra credit, both for undergrads and grads (undergrads: up to 10%; grads: up to 5%).
  • (5%) Deal with image alignment (e.g. the sea images. We recommend Ward's median method (talk to me and I can point you in the right direction), but probably single-scale to make life easier yet slower. Alternatively, you can simulate the clipping in the darker of two images.
  • (5%) Derive better weights by taking noise into account. You can focus on photon noise alone. This should give you an estimate of standard deviation (or something proportional to the standard deviation) for each pixel value in each image. Use a formula for the optimal combination as a function of variance to derive your weights while still properly avoiding clipped black and white pixels. Evaluate and compare with respect to the results using the naive binary weights.
  • (5%) Write a function to calibrate the response curve of a camera. See http://www.pauldebevec.com/Research/HDR/
  • (10%) Implement the bilaterial grid for fast bilateral filtering. See http://groups.csail.mit.edu/graphics/bilagrid/ with more mathematical justifications at http://people.csail.mit.edu/sparis/publi/2009/ijcv/Paris_09_Fast_Approximation.pdf
  • (10%) Hard: deal with moving objects.

Submission

Turn in your files using Canvas and make sure all your files are in the a5 directory under the root of the zip file. Include all sources (.cpp and .h) files, any of your images, and the output of your program. Don't include your actual executable (we don't need your _build directory), and remove any superfluous files before submission.

In your readme.txt file, you should also answer the following questions:

Acknowledgments: This assignment is based off of one designed by Frédo Durand, Katherine L. Bouman, Gaurav Chaurasia, Adrian Vasile Dalca, and Neal Wadhwa for MIT's Digital & Computational Photography class.