Fred's ImageMagick Scripts



    Licensing:

    Copyright © Fred Weinhaus

    My scripts are available free of charge for non-commercial use, ONLY.

    For use of my scripts in commercial (for-profit) environments or non-free applications, please contact me (Fred Weinhaus) for licensing arrangements. My email address is fmw at alink dot net.

    If you: 1) redistribute, 2) incorporate any of these scripts into other free applications or 3) reprogram them in another scripting language, then you must contact me for permission, especially if the result might be used in a commercial or for-profit environment.

    Usage, whether stated or not in the script, is restricted to the above licensing arrangements. It is also subject, in a subordinate manner, to the ImageMagick license, which can be found at: http://www.imagemagick.org/script/license.php

TONEMAP1


Enhances the shadows and/or highlight regions in an image using a non-linear log or gamma function.

Download Script

last modified: August 27, 2013



USAGE: tonemap1 [-k kind] [-a amount] [-c colormode] [-m mode] [-s shadows] [-h highlights] [-e edge] [-b blur] [-S saturation] [-C colorspace] [-A] infile outfile
USAGE: tonemap1 [-help]

-k ... kind ......... apply non-linear enhancement; log or gamma; default=log
-a ... amount ....... amount of non-linear enhancement; float>0; default=4
-c ... colormode .... colormode; HSB or HSL; default=HSB
-m ... mode ......... mode of channel enhancement; all or intensity;
..................... default=intensity
-s ... shadows ...... increase/decrease percent brightness in shadows;
..................... positive or negative integer; default=0
-h ... highlights ... increase/decrease percent brightness in highlights;
..................... positive or negative integer; default=0
-e ... edge ......... edge enhancement increase/decrease percent
..................... positive or negative integer; default=-30
-b ... blur ......... blur amount if edge != 0; float>=0; default=5
-S ... saturation ... saturation factor; float>0; increase >1; decrease <1;
..................... default=0.5
-C ... colorproc .... preprocessing to change colorspace to: RGB, sRGB;
..................... default is no change
-A .................. preprocessing to apply autolevel stretch; default is
..................... not to apply autolevel stretch

PURPOSE: Enhances the shadows and/or highlight regions in an image using a non-linear log or gamma function.

DESCRIPTION: DUALTONEMAP enhances the shadows and/or highlight regions in an image using a non-linear function. The non-linear function can be either a log or gamma function. It can be applied to all channels before converting to either HSB or HSL colorspace. Alternately after converting to HSB or HSL colorspace, the non-linear function can be applied just to the intensity (brightness or lightness) channel. The processed intensity image is then separated into a low frequency component (blurred image) and a high frequency component (edge image) using a blur and subtractive method. Next, post processing is done to the intensity image to enhance the brightness in the shadows and/or highlights of the blurred image and to enhance the edges. These two image are then merged and combined with with the hue and (optionally enhanced) saturation channels. Finally the resulting image is converted back to RGB.

ARGUMENTS:

-k kind ... KIND of non-linear enhancement. Choices are log (l) or gamma (g). The log function is a scaled log whose scaling function is 10^amount. The gamma function is a power law whose exponent is the amount. The default=log

-a amount ... AMOUNT of non-linear enhancement. Values are float>0. Note that kind=gamma can process dark image with amounts greater than 1 or bright images with amounts less than 1. Whereas kind=log can only process dark images. The log amounts are exponents for a power of 10. For example a log amount of 3 is equivalent to 1000. Nominal amounts for the log are about 3 to 4. Nominal equivalent amounts for gamma are about twice those for the log, i.e. 6 to 8. The default=4

-c colormode ... COLORMODE is the colorspace in which processing is done. Values are either HSB or HSL. The default=HSB

-m mode ... MODE of non-linear enhancement. That is the channel(s) to which it is applied. Choices are: all (a), or intensity (i). For mode=all, it is applied before converting to HSB or HSL. For mode=intensity, it is appled to the intensity channel, namely, brightness B for HSB or lightness L for HSL. The default=intensity.

-s shadows ... SHADOWS is the increase/decrease percent brightness in the shadows. Values are in range -100<=integer<=100. The default=0

-h highlights ... HIGHLIGHTS is the increase/decrease percent brightness in the highlights. Values are in range -100<=integer<=100. The default=0

-e edge ... EDGE is the edge enhancement increase/decrease percent. Values are in range -100<=integer<=100. Nominal values will generally be positive. The default=50

-b blur ... BLUR is the amount of blurring to use when edge is not zero. Values are floats>=0. The default=5.

-S saturation ... SATURATION is the saturation increase/decrease factor. Values are floats>=0. Values larger than 1 increase the saturation. Values smaller than 1 decrease the saturation. For mode=all, nominal values are about 2. For mode=intensity, nominal values are about 0.5. The default=0.5

-C colorproc ... COLORPROC is an optional preprocessing step to convert the input image from some other colorspace to either RGB or sRGB. This seems to be needed for HDR Radiance images in XYZ colorspace (.hdr suffix) prior to a bug fix in .hdr images in IM 6.7.2.0. The choices are: RGB and sRGB. The default is no change. Note that somewhere between IM 6.7.5.5 and IM 6.7.6.7, colorspace RGB and sRGB were swapped to correct their meaning.

-A ... Optional AUTOLEVEL preprocessing step. Generally this will not be needed, especially for HDR image with very high dynamic range that require processing in IM HDRI mode. Using it on such images generally cause changes in color or causes the images to become dark.

Requirements: IM 6.4.2-1 or higher to support -evaluate log and IM 6.5.5-1 to support -auto-level, if -A option is used.

Note: For IM 6.7.5.5 or higher, in order to reproduce some of the examples below, one may have to add, remove or change -C arguments, due to the swap of the meaning of -colorspace RGB and -colorspace sRGB. Also if -c is not none for .hdr images, then some parameter changes may be needed. For IM 6.7.4.1 to 6.7.6.6, the processing of lampickaHDR_small.hdr cannot reproduce the examples posted. For more details, see http://www.fmwconcepts.com/imagemagick/tonemap1/tonemap_tests.txt

Reference: http://www.nchu.edu.tw/~add/budget/student%20abroad/inter-meeting-95/T95-2-19.pdf

CAVEAT: No guarantee that this script will work on all platforms, nor that trapping of inconsistent parameters is complete and foolproof. Use At Your Own Risk.


EXAMPLES

(Processed With Q16 HDRI IM Compile)


Example 1 -- mode=all -- variation in edge enhancement

Original Displayed As JPEG
(Actual EXR Image Used)
(source image web site)

Arguments:
-m all -s 0 -h -10 -e 0 -S 2.5

Arguments:
-m all -s 0 -h -10 -e 100 -S 2.5



Example 2 -- mode=intensity -- variation in edge enhancement

Original Displayed As JPEG
(Actual EXR Image Used)
(source image web site)

Arguments:
-m intensity -s 0 -h -10 -e 0 -S 0.5

Arguments:
-m intensity -s 0 -h -10 -e 100 -S 0.5



Example 3 -- mode=all vs mode=intensity

Original Displayed As JPEG
(Actual EXR Image Used)
(source image web site)

Arguments:
-m all -s 30 -h -10 -e 50 -S 2

Arguments:
-m intensity -s 30 -h -10 -e 50 -S 0.6



Example 4 -- mode=all vs mode=intensity

Original Displayed As JPEG
(Actual EXR Image Used)
(source image web site)

Arguments:
-m all -s 30 -h -10 -e 50 -S 2

Arguments:
-m intensity -s 30 -h -10 -e 50 -S 0.5



Example 5 -- mode=all vs mode=intensity

Original Displayed As JPEG
(Actual EXR Image Used)
(source image web site)

Arguments:
-m all -s 20 -h -10 -e 100 -S 2

Arguments:
-m intensity -s 20 -h -10 -e 100 -S 0.5



Example 6 -- mode=all vs mode=intensity

Original Displayed As JPEG
(Actual HDR Image Used)
(source image web site)

Arguments:
-m all -s -10 -h 0 -e 100 -S 2.5 -C sRGB

Arguments:
-m intensity -s -10 -h 0 -e 100 -S 0.5 -C sRGB



Example 7 -- mode=all vs mode=intensity

Original Displayed As JPEG
(Actual HDR Image Used)
(source image web site)
(NOTE: Processed after .hdr bug fix at IM 6.7.2.0)

Arguments:
-m all -s -40 -h -40 -e 100 -S 3

Arguments:
-m intensity -s -40 -h -40 -e 100 -S 0.4



What the script does is as follows for mode=intensity:

  • Converts the image to HSB or HSL colorspace and separate channels
  • Enhance the saturation channel
  • Apply the non-linear function to the intensity channel (B or L)
  • Blur the enhanced intensity channel
  • Subtract the blurred intensity channel
    from the non-blurred intensity channel to form an edge image
  • Enhance the blurred intensity channel
  • Enhance the edge image
  • Add the edge image with the blurred image as a modified intensity image
  • Combine the original Hue channel with the modified Saturation
    channel and the modified intensity channel and converts back to RGB

This is equivalent to the following IM commands for mode=intensity:

  • if [ "$cspace" = "none" ]; then
    cproc=""
    else
    cproc="-set colorspace $cspace"
    fi
  • if [ "$alevel" = "yes" ]; then
    aproc="-auto-level"
    else
    aproc=""
    fi
  • convert -quiet -regard-warnings "$infile" -alpha off $cproc $aproc +repage "$tmpA1"
  • if [ "$kind" = "log" ]; then
    amount=`convert xc: -precision 8 -format "%[fx:10^$amount]" info:`
    proc0="-evaluate log $amount"
    elif [ "$kind" = "gamma" ]; then
    proc0="-gamma $amount"
    fi
  • if [ "$sat" = "1" ]; then
    saturation=""
    else
    saturation="-evaluate multiply $sat"
    fi
  • ssign=`convert xc: -format "%[fx:sign($shadows)==-1?1:0]" info:`
  • hsign=`convert xc: -format "%[fx:sign($highlights)==-1?1:0]" info:`
  • mlo=0
  • mhi=100
  • plo=0
  • phi=100
  • if [ "$shadows" != "0" -a $ssign -eq 1 ]; then
    mlo=$((-shadows))
    elif [ "$shadows" != "0" -a $ssign -eq 0 ]; then
    plo=$shadows
    fi
  • if [ "$highlights" != "0" -a $hsign -eq 1 ]; then
    phi=$((100+highlights))
    elif [ "$highlights" != "0" -a $hsign -eq 0 ]; then
    mhi=$((100-highlights))
    fi
  • if [ $mlo -eq 0 -a $mhi -eq 100 ]; then
    proc1=""
    else
    proc1="-level $mlo,$mhi%"
    fi
  • if [ $plo -eq 0 -a $phi -eq 100 ]; then
    proc2=""
    else
    proc2="+level $plo,$phi%"
    fi
  • edge=`convert xc: -format "%[fx:1+$edge/100]" info:`
  • eproc="-evaluate multiply $edge"
  • convert $tmpA1 -colorspace $colormode -separate \
    \( -clone 1 $saturation \) \
    \( -clone 2 $proc0 \) \
    \( -clone 4 -blur 0x$blur \) \
    \( -clone 4 -clone 5 +swap -compose minus -composite $eproc \) \
    \( -clone 5 $proc1 $proc2 \) \
    \( -clone 6 -clone 7 -compose plus -composite \) \
    -delete 1,2,4,5,6,7 -set colorspace $colormode -combine -colorspace RGB \
    $outfile