# The variable dynamic range approach of SImg

The dynamic range is the interval between the smallest and the largest possible pixel value. Fixing the dynamic range would mean that pixel values are limited to upper and lower limits.

For example Gimp uses a fixed dynamic range, namely [0:255]. If you add two images all pixel values in the sum that are greater then 255 are set to 255. SImg behaves different. This article tries to explain these differences and what it means for the processing.

## The variable dynamic range approach of SImg

SImg internally uses a floating point format during the processing and also allows to store these floating point data directly using the SIF and FITS image formats. So there exist no (relevant) limits for the pixel values. In Simg the dynamic range is the interval between the smallest and the larges pixel value, i.e. the dynamic range is variable.

When the image is stored as an integer image, the entire dynamic range of the floating point image is transformed to the output dynamic range. That means, if the dynamic range of the floating point image is [a,b], and the image is saved in 16bit format, the smallest pixel value a is saved as 0, the largest pixel value b is saved as 65535 and the pixel value (a+b)/2 is saved as 32768. If possible an offset and a factor is stored in the integer image which allows to transform the output dynamic range back to the original one (in the example: [0,65536] → [a,b]). If these offset and factor does not exist, integer images are transformed to the dynamic range [0,1], i.e. 8 bit images are divided by 255 and 16 bit images are divided by 65535.

## What does that mean for processing of integer images?

Lets say you want deconvolve a 8bit image (i.e. the input dynamic range is [0,255] and transformed to [0:1] internally) using a PSF with the sum of 1. After the deconvolution the dynamic range is for example [-0.1,1.4]. When this output is saved as an 8 bit image the entire dynamic range is transformed to [0,255] and thus the contrast is reduced by the factor 0.67 ( = 1/(1.4-(-0.1) ). To avoid this the dynamic range needs to be cropped, e.g. using `simg histcut -l \$l -u \$u`, where \$l specifies the lower quantile (e.g. l=1%) and \$u specifies the upper quantile (e.g. u=99%). Cropping of the dynamic range means that all pixel values smaller than a lower limit are set to that lower limit and all values larger than a upper limit are set to the upper limit.

Cropping the dynamic range to an absolute dynamic range is possible using `simg histcut -la -l \$l -ua -u \$u`, where u and l are absolute limits. (For the example above `simg histcut -la -l 0 -ua -u 1` may be a good choice.) But usually this makes no sense since in practise, after many processing steps a suitable absolute dynamic is unknown and it is easier to find a relative one using the quantiles.

## Advantage against a fixed dynamic range approach

Lets consider a simple example: You want to divide a dark image by a bright image (a usual flat field correction) using fixed dynamic ranges of [0:255]. Plain division leads to a nearly black result, because the quotient is mostly <1.

Of course one can multiply the quotient with 255. But if you then divide a bright image by a dark image the quotient becomes nearly white. Even with more sophisticated multiplicators, a simple operation like division would always lead to the risk of information loss.

The only way to avoid this is using an approach, where the dynamic range can be adjusted, like the approach presented above.