Completed

HDR Imaging Pipeline

From-scratch implementation of the Debevec & Malik (1997) HDR pipeline in NumPy - camera response recovery, handheld RANSAC alignment, and tone mapping

PythonNumPyComputer VisionHDRImage Processingscikit-imageOpenCV

Overview

A complete implementation of the Debevec & Malik (1997) high dynamic range imaging pipeline, built from scratch in NumPy as a CS484 final project. The pipeline takes a bracketed set of photographs (the same scene at multiple exposure times) and recovers a single linear radiance map capturing detail across the full dynamic range (from deep shadows to bright highlights) then compresses it into a displayable image using two tone mapping operators.

Key Contributions

  • Camera response recovery: Solves for the inverse response function $g = \log(f^{-1})$ via a weighted least-squares system (Szeliski Eq. 10.7), with hat weighting to down-weight saturated and near-black pixels
  • Joint exposure estimator: Alternating solver that estimates unknown exposure times directly from pixel data when EXIF metadata is absent or unreliable - critical for sequences where shutter speed values are rounded or missing
  • Chained RANSAC alignment: Matches adjacent exposure pairs (not each frame directly to the reference) using CLAHE-enhanced Harris + BRIEF features, then composes homographies to a common reference frame. This handles 11-exposure handheld sequences spanning ~13 stops where the darkest and brightest images share almost no visible content
  • Dual tone mapping: Global Reinhard (2002) implemented from scratch; Mantiuk (2006) via OpenCV wrapper with NaN/Inf handling

Results

Evaluated on scenes ranging from 3-exposure tripod sequences to an 11-exposure handheld cave sequence. Reinhard produces clean, natural results on most scenes; Mantiuk has an advantage on scenes with extreme local contrast at the cost of some global contrast and occasional halo artifacts.

Technologies

  • NumPy: all core numerical computation - least-squares solving, matrix operations, array manipulation
  • Pillow: image loading, saving, and EXIF metadata extraction
  • Matplotlib: visualization throughout - exposure plots, response curves, radiance maps, tone-mapped outputs
  • scikit-image: Harris corner detection, BRIEF descriptors, RANSAC homography fitting, CLAHE preprocessing, projective warping
  • OpenCV: Mantiuk (2006) tone mapping operator only - all other stages are pure NumPy