P3 Tonemapper Architecture Description

Harrison Ainsworth

http://www.hxa.name/tonemapper/
ARTIFEX (ατ) HXA7241 (dοτ) ORG

2005-11-26

Copyright (c) 2005, Harrison Ainsworth / HXA7241.

Contents

Proposition

Develop a premium tone-mapper component available as source code, library and executable.

Implement Ward Larson's 1997 paper:

‘A Visibility Matching Tone Reproduction Operator for High Dynamic Range Scenes’
Ward Larson, Rushmeier, Piatko;
IEEE TVCG 1997.

http://radsite.lbl.gov/radiance/papers/lbnl39882/tonemap.pdf

Tone mapping is a necessary stage of rendering, but it is usually an afterthought. A good component could fill a gap in the open-source rendering world. It can be well-separated and made reusable without architectural ramifications. It is quite small and simple, so do-able in a month or two.

Aims:

Requirements

Requirements are simple: there is only one use case, and a few supplementary features. The use case follows basic command-line tool form: read a file, process it, output a file. But this is augmented with an options file containing switches and metadata.

Use Case

(actor - user, or renderer)

  1. issue command, input command file
  2. input HDR image (XYZ, RGB (maybe with conversion)) (RGBE or OpenEXR)
  3. (maybe read output error file, then repeat from first step)
  4. receive RGB int (8 or 16 bit) image file (PNG or PPM)

Use Case Features

Analysis

The primary division separates the user-interface application from the library. In the library the tonemapping specific algorithm is separated from more general graphics and utilities parts. In the application the image file formatting is separated.

Packages

reuse (and extend a little):

Package Dependencies

reused

Design

The main tonemap package classes fall into three groups: some specialised images, some image operators, and one overall workflow-context.

Components/Libraries Reused

image file format support:

Class Interfaces

Sequences

  1. read commands
  2. read original image file
  3. make PerceptualMap object
  4. map original image to final image
    1. make foveal image
    2. apply human viewer limitations
      1. make veil image
      2. mix veil into foveal image
      3. mix veil into original image
      4. adjust original image for color sensitivity
      5. filter original image for acuity
    3. make ToneAdjustment
      1. make histogram
      2. adjust histogram
      3. make cumulative function from histogram
    4. map original image with ToneAdjustment
  5. write final image file

Deployment

A simple, basic form eases portability, and the usage is simple, so: a command-line program is best. This can be a thin wrapper to control a dynamic-link/shared library. Maybe the image format readers could be externalised as plugins.

Implementation

Just straightforward, portable C++.

Test

Not decided yet... Something precise and numerical is desirable. There are some source and result images, using the same algorithm, at: http://www.anyhere.com/gward/hdrenc/pages/originals.html , and some calibrated images at: http://www.mpi-inf.mpg.de/resources/hdr/gallery.html

Technical Notes

  1. input original image

    • pixels: RGB float (maybe with color space)
  2. make image of foveal values

    • pixels: RGB float
    • (box/cheap) filter to 1degree/pixel size
    • pixelcount = 2 * tan( viewangle / 2 ) / 0.01745
  3. human viewer

    • make image of veil, from foveal image

      • pixels: RGB float
      • same resolution as foveal image
      • (color, not just luminance)
      • (slowest part - big convolution ...)
    • mix veil into foveal

    • mix veil into original

      • (with a bilinear interpolation)
    • adjust original image for color sensitivity

      • needs conversion to XYZ (to get foveal luminance)
    • filter original image for acuity

      • needs conversion to XYZ (to get foveal luminance)
      • variable blur - mipmap?
  4. make histogram, from foveal image

    • needs conversion to XYZ
    • elements: log10 of luminances
    • 100 bins
    • min = min val, clamped to min of 10^-4
    • max = max val
    • log10lum -> log10lum
    • (linearly interpolatable)
  5. adjust histogram

    • clamp counts, using iterative convergence
      • linear ceiling - ideal viewer
      • varying ceiling - human viewer
  6. map original image with histogram

  7. output final image

    • pixels: RGB int

command file:

(luminance is cd/m^2, remember?)

Plan

estimate

elaboration order

  1. image types
  2. color conversion
  3. tonemap
    1. PerceptualMap
    2. Foveal
    3. Veil
    4. ToneAdjustment
    5. AcuityFilter
    6. ColorAdjustment
  4. formatting

construction order

  1. basic skeleton app
  2. image types
  3. color conversion
  4. PerceptualMap
  5. Foveal
  6. Veil
  7. ToneAdjustment
  8. AcuityFilter
  9. ColorAdjustment
  10. basic formatters
  11. user application
  12. other formatters

next version prospectus

References

Time

inception

1.65

elaboration

9

updating

1.75