v9.1.1
Menu

Exposure Fusion

Implement exposure fusion to blend multiple exposures without HDR tonemapping, leveraging quality metrics to produce a seamless image. This technique is crucial in HDR Imaging as it allows for the combination of differently exposed images, capturing a wider dynamic range.

Exposure fusion directly blends images using weight maps based on contrast, saturation, and well-exposedness. Each input is an H×W×3H \times W \times 3 image with 8-bit values (0–255); first scale every image to [0,1][0, 1]. Then, for each image and each pixel, with gg the grayscale value (mean of R, G, B):

  1. Contrast C=∣∇2g∣C = |\nabla^2 g|: the absolute value of the 4-neighbour discrete Laplacian of gg (sum of the four neighbours minus 4 times the centre; at the border the edge pixels are mirrored), divided by its maximum over the image plus 10−810^{-8}.
  2. Saturation S=std(R,G,B)S = \text{std}(R, G, B): the (population) standard deviation across the colour channels.
  3. Well-exposedness E=exp⁡(−(g−0.5)22σ2)E = \exp\left(-\frac{(g - 0.5)^2}{2\sigma^2}\right), a Gaussian centred at 0.5 with σ=0.2\sigma = 0.2.
W=(C+0.1) (S+0.1) EW = (C + 0.1)\,(S + 0.1)\,E

Normalise the weights across the images so they sum to 1 at every pixel (use max⁡(∑kWk,10−8)\max(\sum_k W_k, 10^{-8}) as the denominator), then blend: F=∑kW^kIkF = \sum_k \hat{W}_k I_k, with the same weight applied to all three channels. Clip FF to [0,1][0, 1], multiply by 255 and convert to 8-bit unsigned integers (truncating). Return an H×W×3H \times W \times 3 array.

This technique is widely used in digital photography to capture high-contrast scenes.

Example

Input
images = [dark_exposure, medium_exposure, bright_exposure]
Output
Fused image with details from all exposures
Reasoning
  • Input: images holds exposures of one scene, each an H×W×3H \times W \times 3 array of 8-bit values. Simplest case: flat grey 5×55 \times 5 frames at 0 (dark), 128 (medium) and 255 (bright), which scale to 00, 0.5020.502 and 11.
  • Contrast and saturation: a flat frame has no edges, so C=0C = 0; R = G = B, so S=0S = 0. Each weight shrinks to 0.1⋅0.1⋅E=0.01E0.1 \cdot 0.1 \cdot E = 0.01E; the +0.1+0.1 offsets stop it collapsing to zero.
  • Well-exposedness (2σ2=0.082\sigma^2 = 0.08): dark e−0.25/0.08=e−3.125≈0.0439e^{-0.25/0.08} = e^{-3.125} \approx 0.0439, medium ≈0.99995\approx 0.99995, bright ≈0.0439\approx 0.0439.
  • Normalise: dividing by their total gives about 0.04040.0404, 0.91920.9192, 0.04040.0404.
  • Blend: 0.0404⋅0+0.9192⋅0.502+0.0404⋅1≈0.50180.0404 \cdot 0 + 0.9192 \cdot 0.502 + 0.0404 \cdot 1 \approx 0.5018; times 255 is 127.96127.96, stored as 127 at every pixel of a 5×5×35 \times 5 \times 3 result.
  • Notice: the medium frame dominates, sitting nearest 0.5. In real photos CC and SS vary per pixel, so each region borrows from the exposure that shows it best: a fused image with details from all exposures.

Constraints

  • images: List of differently exposed images
  • Return: Fused image

More from CV: Computational Photography

PRO

Editor locked

The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.

solution.py

Test results

Sign in to run your code against the test cases.