\input auxmac
\input texinfo


@c
@c Header
@c

@c %**start of header
@setfilename enfuse.info
@include versenfuse.texi
@settitle Fusing Multiple Images with Enfuse @value{VERSION}
@include auxmac.texi
@include varsenfuse.texi
@include config-h.texi

@set default-image-cache-cachesize 1024@dmn{MB}
@set default-image-cache-blocksize 2048@dmn{KB}

@c Define a new index for syntactic comments.
@defcodeindex sc
@c Define a new index for options.
@defcodeindex op
@c %**end of header


@c
@c Categorization for the GNU Info System
@c

@dircategory Individual utilities

@direntry
* enfuse: (enfuse).                     Fuse images using a multiresolution spline.
@end direntry


@c
@c Summary Description and Copyright
@c

@copying
This manual is for Enfuse (version @value{VERSION}, @value{UPDATED}),
a program to merge different exposures of the same scene to produce an
image that looks much like a tonemapped image.

Copyright @copyright{} 2004--2014 @sc{Andrew Mihal}.

@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the @acronym{GNU} Free Documentation License,
Version 1.2 or any later version published by the Free Software
Foundation; with no Invariant Sections, no Front-Cover Texts and no
Back-Cover Texts.  A copy of the license is included in the section
entitled ``@acronym{GNU} Free Documentation License''.
@end quotation
@end copying


@c
@c Title Page and Copyright
@c

@titlepage
@title Enfuse
@subtitle Fusing Multiple Images
@subtitle with Enfuse version @value{VERSION}, @value{UPDATED}

@author Andrew Mihal

@page
@vskip 0pt plus 1fill
@insertcopying
@end titlepage


@ifnothtml
@summarycontents
@end ifnothtml
@contents


@c For the TeX output the List-of-Tables and List-of-Figures appear
@c right after the Table-of-Contents.  In all other formats they go
@c right before the indices.
@iftex
@c Adjust page number so that we get roman numerals for the
@c List-of-Tables and List-of-Figures.  This screws up Texinfo's page
@c count so that we must undo it later.
@tex
\global\pageno=-4
@end tex

@unnumbered List of Tables
@listoffloats Table


@unnumbered List of Figures
@listoffloats Figure
@end iftex


@c
@c ``Top'' Node and Master Menu
@c

@ifnottex
@node Top
@top Enfuse

This manual is for Enfuse (version@tie{}@value{VERSION},
@value{UPDATED}), a program to merge different exposures of the same
scene to produce an image that looks much like a tonemapped image.
@end ifnottex

@menu
* Overview::                    Overview of Enfuse's features
* Workflow::                    Enfuse's role in combining images
* Invocation::                  Command line options and arguments
* Color Profiles::              How Enblend handles @acronym{ICC} color profiles
* Weighting Functions::         Description of all weighting functions
* Understanding Masks::         How to interpret masks and mask files
* Tuning Memory Usage::         Balancing @acronym{RAM} and swap
* Applications::                Possible applications of Enfuse
* Helpful Programs::            Useful other programs
* Bug Reports::                 How to write bug reports
* Authors::                     Major contributors
* FDL::                         @acronym{GNU} Free Documentation License
@ifnotdocbook
* List of Tables::              List of all tables
* List of Figures::             List of all figures
* Program Index::               Names of programs referenced
* Syntactic-Comment Index::     Keys of syntactic comments
* Option Index::                Index of all options
* General Index::               Topic index
@end ifnotdocbook

@detailmenu

--- The Detailed Node Listing ---

Overview

Workflow

* Standard Workflow::           The usual, all-in-one thing
* External Mask Manipulation::  Fiddling around with the masks yourself


Invocation

* Common Options::              General options
* Extended Options::            Memory control and others
* Fusion Options::              Image fusion control
* Expert Options::              Local contrast and local entropy selection configuration
* Option Delimiters::           How to separate options' arguments

Color Profiles

Weighting Functions

* Weighting Pixels::            General concept of weighting pixels
* Exposure Weighting::          Weighting by exposure
* Saturation Weighting::        Weighting by saturation
* Local Contrast Weighting::    Weighting by local contrast
* Local Entropy Weighting::     Weighting by local entropy

Weighting Algorithms

* Weighted Average::            Enfuse's default weighting algorithm
* Disabling Averaging::         ``Super Trouper'' weighting for focus stacks

Local Contrast Weighting

* Standard Deviation::          Standard deviation (@acronym{SDev}) in a square of pixels
* Laplacian of Gaussian::       @acronym{LoG}, a second derivative method
* Blend SDev and LoG::          Mix both methods
* Scaling and Choice of Mode::  How parameters do not scale; neither does mode

Understanding Masks

Tuning Memory Usage

Applications

* What Images::                 What makes images fusable?
* Repetition::                  Just taking the same shot multiple times
* Exposure Series::             Varying the exposure time
* Flash Exposure Series::       Varying the flash output
* Polarization Series::         Changing the polarizer angle
* Focus Stacks::                Stacking images with different in-focus distance

Exposure Series

* Exposure Series Tips::            Some hints for beginners
* Exposure Series Misconceptions::  What works despite the hype

Focus Stacks

* Why Focus Stacks::            Why take the hassle?
* Preparing Focus Stacks::      How to get suitable input images
* Local Contrast Based Fusing:: Fundamental command line options
* Basic Focus Stacking::        Simple, standard deviation method
* Advanced Focus Stacking::     Advanced, Laplacian technique
* Expert Stacking::             Tips for focus stacking experts

Advanced Focus Stacking

* Local Contrast Problem::        What is the problem Kenneth?
* Laplacian Edge Detection::      Using a Laplacian-of-Gaussian to detect edges
* Local Contrast Enhancement::    Boosting local contrast before weighting
* Suppressing Noise or Recognizing Faint Edges::  The best of both worlds
* Focus Stacking Decision Tree::  What to do and how to fuse

Helpful Programs

Bug Reports

Authors

FDL
@end detailmenu
@end menu


@c
@c Document Body
@c

@node Overview
@chapter Overview

@c Undo the roman page numbering we used for the Table-of-Contents,
@c the List-of-Tables, and the List-of-Figures.
@tex
\global\pageno=1
@end tex

@cindex overview

@cindex Mertens-Kautz-Van Reeth exposure fusion
Enfuse merges overlapping images using the
@sc{Mertens}-@sc{Kautz}-@sc{Van Reeth} exposure fusion
algorithm.@footnote{Tom Mertens, Jan Kautz, and Frank van Reeth,
``Exposure Fusion'', Proceedings of the 15th Pacific Conference on
Computer Graphics and Applications, pages 382--390.}  This is a quick
way for example to blend differently exposed images into a nice output
image, without producing intermediate high-dynamic range
(@acronym{HDR}) images that are then tonemapped to a viewable image.
This simplified process often works much better than tonemapping
algorithms.

Enfuse can also be used to build extended depth-of-field
(@acronym{DOF}) images by blending a focus stack.

The idea is that pixels in the input images are weighted according to
qualities such as, for example, proper exposure, good local contrast,
or high saturation.  These weights determine how much a given pixel
will contribute to the final image.

@cindex Burt-Adelson multiresolution spline
A @sc{Burt}-@sc{Adelson} multiresolution spline blender@footnote{Peter
J. Burt and Edward H. Adelson, ``A Multiresolution Spline With
Application to Image Mosaics'', @acronym{ACM} Transactions on
Graphics, @abbr{Vol@.}  2, @abbr{No@.} 4, October 1983, pages
217--236.} is used to combine the images according to the weights.
The multiresolution blending ensures that transitions between regions
where different images contribute are difficult to spot.

Enfuse uses up to four criteria to judge the quality of a pixel, which
@ref{Table:weighting-criteria} briefly describes.

@float Table,Table:weighting-criteria
@table @asis
@dbtitle{Weighting Criteria}
@item Exposure
@cindex weighting, exposure
The exposure criteria favors pixels with luminance close to the middle
of the range.  These pixels are considered better exposed than those
with high or low luminance levels.

@item Saturation
@cindex weighting, saturation
The saturation criteria favors highly-saturated pixels.  (Note that
saturation is only defined for color pixels.)

@item Local Contrast
@cindex weighting, local contrast
The contrast criteria favors pixels inside a high-contrast
neighborhood.  Enfuse can use standard deviation, Laplacian magnitude,
or a blend of both as local contrast measure.

@item Local Entropy
@cindex weighting, local entropy
The entropy criteria prefers pixels inside a high-entropy
neighborhood.  In addition, Enfuse allows the user to mitigate the
problem of noisy images when using entropy weighting by setting a
black threshold.
@end table

@caption{Enfuse's four weighting criteria.  (Also see @ref{Table:default-weights} for the default weights of these criteria.)}

@shortcaption{Weighting criteria}
@end float

For the concept of pixel weighting, and details on the different
weighting functions, see @ref{Weighting Functions}.

Adjust how much importance is given to each criterion by setting the
weight parameters on the command line.  For example, if you set
@samp{--exposure-weight=1.0} and @samp{--saturation-weight=0.5},
Enfuse will favor well-exposed pixels over highly-saturated pixels
when blending the source images.  The effect of these parameters on
the final result will not always be clear in advance.  The quality of
the result is subject to your artistic interpretation.  Playing with
the weights may or may not give a more pleasing result.  The authors
encourage you to experiment, perhaps using
down-sized@footnote{Downsampling with a good interpolator reduces
noise, which might not desired to judge the image quality of the
original-size image.  Cropping might be an alternative, though.} or
cropped images for speed.

@cindex alpha channel
@cindex channel, alpha
Enfuse expects but does not require each input image to have an alpha
channel.  By setting the alpha values of pixels to zero, users can
manually remove those pixels from consideration when blending.  If an
input image lacks an alpha channel, Enfuse will issue a warning and
continue assuming all pixels should contribute to the final output.
Any alpha value other than zero is interpreted as ``this pixel should
contribute to the final image''.

@cindex multi-layer image
@cindex image, multi-layer
@cindex multi-directory @acronym{TIFF}
@cindex @acronym{TIFF}, multi-directory
@cindex @command{tiffcopy}
@cindex @command{tiffsplit}
Enfuse reads all layers of multi-layer images, like, for example,
multi-directory @acronym{TIFF} images@footnote{Use utilities like,
e.g., @command{tiffcopy} and @command{tiffsplit} of LibTIFF to
manipulate multi-directory @acronym{TIFF} images.  @xref{Helpful
Programs}.}.  The input images are processed in the order they appear
on the command line.  Multi-layer images are processed from the first
layer to the last before Enfuse considers the next image on the
command line.

@cindex SourceForge
Find out more about Enfuse on its @uref{http://@/sourceforge.net/,
SourceForge} @uref{http://@/enblend.sourceforge.net/, web page}.


@node Workflow
@chapter Workflow
@cindex workflow

Enfuse is a part of a chain of tools to assemble images.  It merges
photos of the same subject at the same location and same direction,
but taken with varying exposure parameters.

@menu
* Standard Workflow::           The usual, all-in-one thing
* External Mask Manipulation::  Fiddling around with the masks yourself
@end menu


@node Standard Workflow
@section Standard Workflow
@cindex workflow, standard

@include workflow.texi


@node External Mask Manipulation
@section External Mask Manipulation
@cindex workflow, external mask manipulation

@include external-masks.texi


@node Invocation
@chapter Invocation
@cindex invocation

@command{enfuse} [@var{OPTIONS}] [@code{--output=}@var{IMAGE}]
@var{INPUT}@enddots{}

@noindent
Fuse the sequence of images @var{INPUT}@dots{} into a single
@var{IMAGE}.

@cindex literal filename
@cindex filename, literal
@cindex response file
Input images are either specified literally or via so-called response
files (see below).  The latter are an alternative to specifying image
filenames on the command line.


@menu
* Image Requirements::          Input image requirements
* Response Files::              Files listing the images' names
* Common Options::              General options
* Extended Options::            Memory control and others
* Fusion Options::              Image fusion control
* Expert Options::              Local contrast and local entropy selection configuration
* Option Delimiters::           How to separate options' arguments
@end menu


@node Image Requirements
@section Image Requirements
@cindex input image requirements

All input images must comply with the following requirements.

@itemize
@item
The images overlap.

@item
The images agree on their number of bits-per-channel, this is, their
``depth'':
@itemize --
@item
@code{UINT8},
@item
@code{UINT16},
@item
@code{FLOAT},
@item
etc.
@end itemize

See option@tie{}@option{--depth} below for an explanation of different
(output) depths.

@item
Enfuse understands the images' filename extensions as well as their
file formats.

You can check the supported extensions and formats by calling Enfuse
with the option pair @option{--version@tie{}--verbose} and scan the
output for @samp{Supported image formats} or @samp{Supported file
extensions}.
@end itemize

Moreover, there are some ``good practices'', which are not enforced by
the application, but almost certainly deliver superior results.

@itemize
@item
Either all files lack an @acronym{ICC} profile, or all images are
supplied with the @emph{same} @acronym{ICC} profile.

@item
If the images' meta-data contains resolution information
(``@acronym{DPI}''), it is the same for all pictures.
@end itemize


@node Response Files
@section Response Files
@cindex response file

@include filespec.texi


@node Common Options
@section Common Options
@cindex options, common

Common options control some overall features of Enfuse.

Enfuse accepts arguments to any option in uppercase as well as in
lowercase letters.  For example, @samp{deflate}, @samp{Deflate} and
@samp{DEFLATE} as arguments to the @code{--compression} option
described below, all instruct Enfuse to use the @sc{Deflate}
compression scheme.  This manual denotes all arguments in lowercase
for consistency.

@table @code
@item --compression=@var{COMPRESSION}
@opindex --compression
@cindex output file compression
@cindex compression
Write a compressed output file.

Depending on the output file format, Enfuse accepts different values
for @var{COMPRESSION}.

@table @asis
@item @acronym{JPEG} format.
@cindex @acronym{JPEG} compression
@cindex compression, @acronym{JPEG}

The compression either is a literal integer or a keyword-option
combination.

@table @code
@item @var{LEVEL}
Set @acronym{JPEG} quality@tie{}@var{LEVEL}, where @var{LEVEL} is an
integer that ranges from 0--100.

@item jpeg[:@var{LEVEL}]
Same as above; without the optional argument just switch on (standard)
@acronym{JPEG} compression.

@item jpeg-arith[:@var{LEVEL}]
@cindex arithmetic @acronym{JPEG} compression
@cindex compression, arithmetic @acronym{JPEG}
Switch on arithmetic @acronym{JPEG} compression.  With optional
argument set the arithmetic compression@tie{}@var{LEVEL}, where
@var{LEVEL} is an integer that ranges from 0--100.
@end table

@item @acronym{TIF} format.
Here, @var{COMPRESSION} is one of the keywords:

@table @code
@item none
Do not compress.  This is the default.

@item deflate
@cindex deflate compression
@cindex compression, deflate
Use the @sc{Deflate} compression scheme also called
@acronym{ZIP}-in-@acronym{TIFF}.  @sc{Deflate} is a lossless data
compression algorithm that uses a combination of the @acronym{LZ77}
algorithm and @sc{Huffman} coding.

@item jpeg[:@var{LEVEL}]
@cindex compression, @acronym{JPEG}
Use @acronym{JPEG} compression.  With optional argument set the
compression@tie{}@var{LEVEL}, where @var{LEVEL} is an integer that
ranges from 0--100.

@item lzw
@cindex @acronym{LZW} compression
@cindex compression, @acronym{LZW}
Use @sc{Lempel}-@sc{Ziv}-@sc{Welch} (@acronym{LZW}) adaptive
compression scheme.  @acronym{LZW} compression is lossless.

@item packbits
@cindex packbits compression
@cindex compression, packbits
Use @sc{PackBits} compression scheme.  @sc{PackBits} is a particular
variant of run-length compression; it is lossless.
@end table

@item Any other format.
Other formats do not accept a @var{COMPRESSION} setting.

However, @uref{http://@/hci.iwr.uni-@/heidelberg.de/@/vigra/,
@acronym{VIGRA}} automatically compresses @file{png}-files with the
@sc{Deflate} method.
@end table

@item --layer-selector=@var{ALGORITHM}
@opindex --layer-selector
@cindex layer selection
@cindex layer selection
Override the standard layer selector algorithm, which is
@samp{@value{src::layer-selector}}.

This version of Enfuse offers the following algorithms:
@table @code
@item all-layers
@cindex layer selection, all-layers
Select all layers in all images.

@item first-layer
@cindex layer selection, first-layer
Select only first layer in each multi-layer image.  For single-layer
images this is the same as @samp{all-layers}.

@item largest-layer
@cindex layer selection, largest-layer
Select largest layer in each multi-layer image, where the
``largeness'', this is the size is defined by the product of the layer
width and its height.  The channel width of the layer is ignored.  For
single-layer images this is the same as @samp{all-layers}.

@item no-layer
@cindex layer selection, no layer
Do not select any layer in any image.

This algorithm is useful to temporarily exclude some images in
response files.
@end table

@item -h
@itemx --help
@opindex -h
@opindex --help
Print information on the available options and exit.

@item -l @var{LEVELS}
@itemx --levels=@var{LEVELS}
@opindex -l
@opindex --levels
@cindex pyramid levels
@cindex levels, pyramid
Use at most this many @var{LEVELS} for pyramid @footnote{As
Dr.@tie{}Daniel Jackson correctly
@uref{http://stargate.wikia.com/@/wiki/@/The_@/Tomb, noted}, actually,
it is not a pyramid: ``Ziggaurat, it's a
@uref{http://en.wikipedia.org/@/wiki/@/Ziggaurat, Ziggaurat}.''}
blending if @var{LEVELS} is positive, or reduce the maximum number of
levels used by @minus{}@var{LEVELS} if @var{LEVELS} is negative;
@samp{auto} or @samp{automatic} restore the default, which is to use
the maximum possible number of levels for each overlapping region.

The number of levels used in a pyramid controls the balance between
local and global image features (contrast, saturation, @dots{}) in the
blended region.  Fewer levels emphasize local features and suppress
global ones.  The more levels a pyramid has, the more global features
will be taken into account.

As a guideline, remember that each new level works on a linear scale
twice as large as the previous one.  So, the zeroth layer, the
original image, obviously defines the image at single-pixel scale, the
first level works at two-pixel scale, and generally, the @math{n}-th
level contains image data at @power{2, n}-pixel scale.  This is the
reason why an image of
@math{width}@classictimes{}@/@math{height}@dmn{pixels} cannot be
deconstructed into a pyramid of more than
@ifinfo
@display
@math{floor(log_2(min(width, height)))}
@end display
@end ifinfo
@html
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
    <mrowinline>
        <mo>&LeftFloor;</mo>
        <mrowinline>
            <msubinline>
                <mo>log</mo>
                <mn>2</mo>
            </msubinline>
            <mo>&ApplyFunction;</mo>
            <mo>(</mo>
            <mrowinline>
                <mo>min</mo>
                <mo>&ApplyFunction;</mo>
                <mfencedinline>
                    <mi mathvariant="italic">width</mi>
                    <mi mathvariant="italic">height</mi>
                </mfencedinline>
            </mrowinline>
            <mo>)</mo>
        </mrowinline>
        <mo>&RightFloor;</mo>
    </mrowinline>
</mathinline>
@end html
@tex
$\lfloor \log_2(\min(\mathit{width}, \mathit{height})) \rfloor$
@end tex
@docbook
<inlineequation>
    <mml:math>
        <mml:apply>
            <mml:floor/>
            <mml:apply>
                <mml:log/>
                <mml:logbase>
                    <mml:cn>2</mml:cn>
                </mml:logbase>
                <mml:apply>
                    <mml:min/>
                    <mml:csymbol>
                        <mml:mi mathvariant="italic">width</mml:mi>
                    </mml:csymbol>
                    <mml:csymbol>
                        <mml:mi mathvariant="italic">height</mml:mi>
                    </mml:csymbol>
                </mml:apply>
            </mml:apply>
        </mml:apply>
    </mml:math>
</inlineequation>&nbsp;
@end docbook
levels.

If too few levels are used, ``halos'' around regions of strong local
feature variation can show up.  On the other hand, if too many levels
are used, the image might contain too much global features.  Usually,
the latter is not a problem, but is highly desired.  This is the
reason, why the default is to use as many levels as is possible given
the size of the overlap regions.  Enfuse may still use a smaller
number of levels if the geometry of the overlap region demands.

Positive values of @var{LEVELS} limit the maximum number of pyramid
levels.  Depending on the size and geometry of the overlap regions
this may or may not influence any pyramid.  Negative values of
@var{LEVELS} reduce the number of pyramid levels below the maximum no
matter what the actual maximum is and thus always influence all
pyramids.  Use @samp{auto} or @samp{automatic} as @var{LEVELS} to
restore the automatic calculation of the maximum number of levels.

The valid range of the absolute value of @var{LEVELS} is
@value{src::minimum-pyramid-levels} to
@value{src::maximum-pyramid-levels}.

@item -o
@itemx --output=@var{FILE}
@opindex -o
@opindex --output
Place output in @var{FILE}.

@cindex @file{@value{src::default-output-filename}}
@cindex default output filename
@cindex output filename, default
If @option{--output} is not specified, the default is to put the
resulting image in @file{@value{src::default-output-filename}}.

@item --parameter=@var{KEY}[=@var{VALUE}]:@dots{}
Set a @var{KEY}-@var{VALUE} pair, where @var{VALUE} is optional.  This
option is cumulative.  Separate multiple pairs with the usual numeric
delimiters.

This option has the negated form @option{--no-parameter},
@opindex --no-parameter
which takes one or more @var{KEY}s and removes them from the list of
defined parameters.  The special key@tie{}@samp{*} deletes all
parameters at once.

Parameters allow the developers to change the internal
workings of Enfuse without the need to recompile.

@item -v
@itemx --verbose[=@var{LEVEL}]
@opindex -v
@opindex --verbose
Without an argument, increase the verbosity of progress reporting.
Giving more @option{--verbose}@tie{}options will make Enfuse more
verbose.  Directly set a verbosity level with a non-negative integral
@var{LEVEL}.

Each level includes all messages of the lower levels.

@table @asis
@item Level
Messages

@item 0
only warnings and errors

@item 1
reading and writing of images

@item 2
mask generation, pyramid, and blending

@item 3
reading of response files, color conversions

@item 4
image sizes, bounding boxes and intersection sizes

@item 5
detailed information on the optimizer runs (Enblend only)

@item 6
estimations of required memory in selected processing steps
@end table

The default verbosity level of Enfuse is
@value{src::default-verbosity-level}.

@item -V
@itemx --version
@opindex -V
@opindex --version
Output information on the Enfuse version.

Team this option with @option{--verbose} to show configuration
details, like the extra features that have been compiled in.

@item -w
@itemx --wrap=@var{MODE}
@opindex -w
@opindex --wrap
@cindex 360@textdegree{} panoramas
@cindex wrap around
Blend around the boundaries of the panorama.

As this option significantly increases memory usage and computation
time only use it, if the panorama will be

@itemize
@item
consulted for any kind measurement, this is, all boundaries must match
as accurately as possible, or

@item
printed out and the boundaries glued together, or

@item
@cindex virtual reality
fed into a virtual reality (@abbr{VR}) generator, which creates a
seamless environment.
@end itemize

Otherwise, always avoid this option!

With this option, Enfuse treats the panorama of width@tie{}@math{w}
and height@tie{}@math{h} as an infinite data structure, where each
pixel@tie{}@math{P(x, y)} of the input images represents the set of
pixels
@ifinfo
@math{S_P(x, y)}
@end ifinfo
@html
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
    <mrowinline>
        <msubinline>
            <mi>S</mi>
            <mi>P</mi>
        </msubinline>
        <mfencedinline>
            <mi>x</mi>
            <mi>y</mi>
        </mfencedinline>
    </mrowinline>
</mathinline>
@end html
@tex
$S_P(x, y)$
@end tex
@docbook
<inlineequation>
    <mml:math>
        <mml:apply>
            <mml:csymbol>
                <mml:msub>
                    <mml:mi>S</mml:mi>
                    <mml:mi>P</mml:mi>
                </mml:msub>
            </mml:csymbol>
            <mml:ci>x</mml:ci>
            <mml:ci>y</mml:ci>
        </mml:apply>
    </mml:math>
</inlineequation>
@end docbook
@footnote{Solid-state physicists will be reminded of the
@uref{http://@/en.wikipedia.org/@/wiki/@/Born-@/von_@/Karman_@/boundary_@/condition,
@sc{Born}-@sc{von@tie{}K@'arm@'an} boundary condition}.}.

@var{MODE} takes the following values:

@table @samp
@item none
@itemx open
This is a ``no-op''; it has the same effect as not giving
@option{--wrap} at all.  The set of input images is considered open at
its boundaries.

@item horizontal
Wrap around horizontally:
@ifinfo
@display
@math{S_P(x, y) = @{P(x + m * w, y): m in Z@}.}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <msub>
            <mi>S</mi>
            <mi>P</mi>
        </msub>
        <mfenced>
            <mi>x</mi>
            <mi>y</mi>
        </mfenced>
        <mo>=</mo>
        <mrow>
            <mo>&lcub;</mo>
            <mrow>
                <mi>P</mi>
                <mfenced>
                    <mrow>
                        <mi>x</mi>
                        <mo>+</mo>
                        <mi>m</mi>
                        <mo>&InvisibleTimes;</mo>
                        <mi>w</mi>
                    </mrow>
                    <mi>y</mi>
                </mfenced>
            </mrow>
            <mo>:</mo>
            <mrow>
                <mi>m</mi>
                <mtext>&ThickSpace;in&ThickSpace;</mtext>
                <mi>Z</mi>
            </mrow>
            <mo>&rcub;</mo>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    S_P(x, y) = \{P(x + m w, y): m \in Z\}.
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:csymbol>
                    <mml:msub>
                        <mml:mi>S</mml:mi>
                        <mml:mi>P</mml:mi>
                    </mml:msub>
                </mml:csymbol>
                <mml:ci>x</mml:ci>
                <mml:ci>y</mml:ci>
            </mml:apply>
            <mml:set>
                <mml:bvar>
                    <mml:apply>
                        <mml:ci>P</mml:ci>
                        <mml:apply>
                            <mml:plus/>
                            <mml:ci>x</mml:ci>
                            <mml:apply>
                                <mml:times/>
                                <mml:ci>m</mml:ci>
                                <mml:ci>w</mml:ci>
                            </mml:apply>
                        </mml:apply>
                        <mml:ci>y</mml:ci>
                    </mml:apply>
                </mml:bvar>
                <mml:condition>
                    <mml:apply>
                        <mml:in/>
                        <mml:ci>m</mml:ci>
                        <mml:ci>Z</mml:ci>
                    </mml:apply>
                </mml:condition>
            </mml:set>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

This is useful for 360@textdegree{} horizontal panoramas as it
eliminates the left and right borders.

@item vertical
Wrap around vertically:
@ifinfo
@display
@math{S_P(x, y) = @{P(x, y + n * h): m in Z@}.}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <msub>
            <mi>S</mi>
            <mi>P</mi>
        </msub>
        <mfenced>
            <mi>x</mi>
            <mi>y</mi>
        </mfenced>
        <mo>=</mo>
        <mrow>
            <mo>&lcub;</mo>
            <mrow>
                <mi>P</mi>
                <mfenced>
                    <mi>x</mi>
                    <mrow>
                        <mi>y</mi>
                        <mo>+</mo>
                        <mi>n</mi>
                        <mo>&InvisibleTimes;</mo>
                        <mi>h</mi>
                    </mrow>
                </mfenced>
            </mrow>
            <mo>:</mo>
            <mrow>
                <mi>n</mi>
                <mtext>&ThickSpace;in&ThickSpace;</mtext>
                <mi>Z</mi>
            </mrow>
            <mo>&rcub;</mo>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    S_P(x, y) = \{P(x, y + n h): n \in Z\}.
$$
@end tex

This is useful for 360@textdegree{} vertical panoramas, as it
eliminates the top and bottom borders.

@item both
@itemx horizontal+vertical
@itemx vertical+horizontal
Wrap around both horizontally and vertically:
@ifinfo
@display
@math{S_P(x, y) = @{P(x + m * w, y + n * h): m, n in Z@}.}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <msub>
            <mi>S</mi>
            <mi>P</mi>
        </msub>
        <mfenced>
            <mi>x</mi>
            <mi>y</mi>
        </mfenced>
        <mo>=</mo>
        <mrow>
            <mo>&lcub;</mo>
            <mrow>
                <mi>P</mi>
                <mfenced>
                    <mrow>
                        <mi>x</mi>
                        <mo>+</mo>
                        <mi>m</mi>
                        <mo>&InvisibleTimes;</mo>
                        <mi>w</mi>
                    </mrow>
                    <mrow>
                        <mi>y</mi>
                        <mo>+</mo>
                        <mi>n</mi>
                        <mo>&InvisibleTimes;</mo>
                        <mi>h</mi>
                    </mrow>
                </mfenced>
            </mrow>
            <mo>:</mo>
            <mrow>
                <mrow>
                    <mi>m</mi>
                    <mo>,</mo>
                    <mi>n</mi>
                </mrow>
                <mtext>&ThickSpace;in&ThickSpace;</mtext>
                <mi>Z</mi>
            </mrow>
            <mo>&rcub;</mo>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    S_P(x, y) = \{P(x + m w, y + n h): m, n \in Z\}.
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:csymbol>
                    <mml:msub>
                        <mml:mi>S</mml:mi>
                        <mml:mi>P</mml:mi>
                    </mml:msub>
                </mml:csymbol>
                <mml:ci>x</mml:ci>
                <mml:ci>y</mml:ci>
            </mml:apply>
            <mml:set>
                <mml:bvar>
                    <mml:apply>
                        <mml:ci>P</mml:ci>
                        <mml:apply>
                            <mml:plus/>
                            <mml:ci>x</mml:ci>
                            <mml:apply>
                                <mml:times/>
                                <mml:ci>m</mml:ci>
                                <mml:ci>w</mml:ci>
                            </mml:apply>
                        </mml:apply>
                        <mml:apply>
                            <mml:plus/>
                            <mml:ci>y</mml:ci>
                            <mml:apply>
                                <mml:times/>
                                <mml:ci>n</mml:ci>
                                <mml:ci>h</mml:ci>
                            </mml:apply>
                        </mml:apply>
                    </mml:apply>
                </mml:bvar>
                <mml:condition>
                    <mml:apply>
                        <mml:and/>
                        <mml:apply>
                            <mml:in/>
                            <mml:ci>n</mml:ci>
                            <mml:ci>Z</mml:ci>
                        </mml:apply>
                        <mml:apply>
                            <mml:in/>
                            <mml:ci>m</mml:ci>
                            <mml:ci>Z</mml:ci>
                        </mml:apply>
                    </mml:apply>
                </mml:condition>
            </mml:set>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

In this mode, both left and right borders, as well as top and bottom
borders, are eliminated.
@end table

Specifying @option{--wrap} without @var{MODE} selects horizontal
wrapping.
@end table


@node Extended Options
@section Extended Options
@cindex options, extended

Extended options control the image cache, the color model, and the
cropping of the output image.

@table @code
@item -b @var{BLOCKSIZE}
@opindex -b
@cindex image cache, block size
Set the @var{BLOCKSIZE} in kilobytes (@acronym{KB}) of Enfuse's image
cache.

This is the amount of data that Enfuse will move to and from the disk
at one time.  The default is @value{default-image-cache-blocksize},
which should be ok for most systems.  See @ref{Tuning Memory Usage}
for details.

Note that Enfuse must have been compiled with the image-cache feature
for this option to be effective.  Find out about extra features with
@code{enfuse --version --verbose}.

@item -c
@itemx --ciecam
@opindex -c
@opindex --ciecam
@cindex color appearance model
@cindex @acronym{CIECAM02}
Force the use of the @acronym{CIECAM02} color appearance model for
blending colors instead of blending inside the @acronym{RGB} color
cube.

@cindex color profile
@cindex @acronym{ICC} profile
@cindex profile, @acronym{ICC}
@cindex @acronym{sRGB} color space
@cindex color space, @acronym{sRGB}
All input files should have identical @acronym{ICC} profiles when this
option is specified.  If no @acronym{ICC} profile is present, Enfuse
assumes that all images use the @acronym{sRGB} color space.
@xref{Color Profiles}.

Please keep in mind that using @acronym{CIECAM02} blending may change
the colors in the output image.

This option can be negated; see option@tie{}@option{--no-ciecam}
below.

@item -d
@itemx --depth=@var{DEPTH}
@opindex -d
@opindex --depth
@cindex bits per channel
@cindex channel width
Force the number of bits per channel and the numeric format of the
output image.

Enfuse always uses a smart way to change the channel depth, to assure
highest image quality (at the expense of memory), whether
requantization is implicit because of the output format or explicit
with option@tie{}@option{--depth}.

@itemize
@item
If the output-channel width is larger than the input-channel width of
the input images, the input images' channels are widened to the output
channel width immediately after loading, that is, as soon as possible.
Enfuse then performs all blending operations at the output-channel
width, thereby preserving minute color details which can appear in the
blending areas.

@item
If the output-channel width is smaller than the input-channel width of
the input images, the output image's channels are narrowed only right
before it is written to disk, that is, as late as possible.  Thus the
data benefits from the wider input channels for the longest time.
@end itemize

All @var{DEPTH} specifications are valid in lowercase as well as
uppercase letters.  For integer format, use

@table @asis
@item @code{8}, @code{uint8}
Unsigned 8@dmn{bit}; range: 0..255
@item @code{int16}
Signed 16@dmn{bit}; range: @minus{}32768..32767
@item @code{16}, @code{uint16}
Unsigned 16@dmn{bit}; range: 0..65535
@item @code{int32}
Signed 32@dmn{bit}; range: @minus{}2147483648..2147483647
@item @code{32}, @code{uint32}
Unsigned 32@dmn{bit}; range: 0..4294967295
@end table

For floating-point format, use

@c Minimum positive normalized value: 2^(2 - 2^k)
@c Epsilon: 2^(1 - n)
@c Maximum finite value: (1 - 2^(-n)) * 2^(2^k)

@table @asis
@c IEEE single: 32 bits, n = 24, k = 32 - n - 1 = 7
@item @code{r32}, @code{real32}, @code{float}
@cindex @acronym{IEEE754} single precision float
@cindex single precision float, @acronym{IEEE754}
@acronym{IEEE754} single precision floating-point, 32@dmn{bit} wide,
24@dmn{bit} significant

@itemize
@item
Minimum normalized value: @semilog{1.2, -38}
@item
Epsilon: @semilog{1.2, -7}
@item
Maximum finite value: @semilog{3.4, 38}
@end itemize

@c IEEE double: 64 bits, n = 53, k = 64 - n - 1 = 10
@item @code{r64}, @code{real64}, @code{double}
@cindex @acronym{IEEE754} double precision float
@cindex double precision float, @acronym{IEEE754}
@acronym{IEEE754} double precision floating-point, 64@dmn{bit} wide,
53@dmn{bit} significant

@itemize
@item
Minimum normalized value: @semilog{2.2, -308}
@item
Epsilon: @semilog{2.2, -16}
@item
Maximum finite value: @semilog{1.8, 308}
@end itemize
@end table

If the requested @var{DEPTH} is not supported by the output file
format, Enfuse warns and chooses the @var{DEPTH} that matches best.

@cindex @acronym{OpenEXR}, data format
The @acronym{OpenEXR} data format is treated as
@acronym{IEEE754}@tie{}float internally.  Externally, on disk,
@acronym{OpenEXR} data is represented by ``half'' precision
floating-point numbers.

@c ILM half: 16 bits, n = 10, k = 16 - n - 1 = 5
@cindex @acronym{OpenEXR}, half precision float
@cindex half precision float, @acronym{OpenEXR}
@uref{http://@/www.openexr.com/@/about.html#@/features,
@acronym{OpenEXR}} half precision floating-point, 16@dmn{bit} wide,
10@dmn{bit} significant

@itemize
@item
Minimum normalized value: @semilog{9.3, -10}
@item
Epsilon: @semilog{2.0, -3}
@item
Maximum finite value: @semilog{4.3, 9}
@end itemize

@item -f @var{WIDTH}x@var{HEIGHT}
@itemx -f @var{WIDTH}x@var{HEIGHT}+x@var{XOFFSET}+y@var{YOFFSET}
@opindex -f
@cindex output image, set size of
@cindex canvas size
@cindex size, canvas
Ensure that the minimum ``canvas'' size of the output image is at
least @var{WIDTH}@classictimes{}@/@var{HEIGHT}.  Optionally specify
the @var{XOFFSET} and @var{YOFFSET}, too.

@pindex nona @r{(Hugin)}
@pindex hugin
This option only is useful when the input images are cropped
@acronym{TIFF} files, such as those produced by
@command{nona}@footnote{The stitcher @command{nona} is part of Hugin.
@xref{Helpful Programs}.}.

Note that option@tie{}@option{-f} neither rescales the output image,
nor shrinks the canvas size below the minimum size occupied by the
union of all input images.

@item --fallback-profile=@var{PROFILE-FILENAME}
@opindex --fallback-profile
@cindex profile, fallback
@cindex fallback profile
@cindex @acronym{CIECAM02}
Use the @acronym{ICC} profile in @var{PROFILE-FILENAME} instead of the
default @acronym{sRGB}.  See option@tie{}@option{--ciecam} and
@ref{Color Profiles}.

This option only is effective if the input images come without color
profiles and blending is performed in @acronym{CIECAM02} color
appearance model.

@item -g
@opindex -g
@cindex alpha channel, associated
Save alpha channel as ``associated''.  See the
@uref{http://@/www.awaresystems.be/@/imaging/@/tiff/@/tifftags/@/extrasamples.html,
@acronym{TIFF} documentation} for an explanation.

@pindex gimp
@pindex cinepaint
Gimp (before version@tie{}2.0) and CinePaint (@pxref{Helpful
Programs}) exhibit unusual behavior when loading images with
unassociated alpha channels.  Use option @option{-g} to work around
this problem.  With this flag Enfuse will create the output image
with the associated alpha tag set, even though the image is really
unassociated alpha.

@item -m @var{CACHESIZE}
@opindex -m
@cindex image cache, cache size
Set the @var{CACHESIZE} in megabytes (@acronym{MB}) of Enfuse's image
cache.

This is the amount of memory Enfuse will use for storing image data
before swapping to disk.  The default is
@value{default-image-cache-cachesize}, which is good for systems with
3--4@dmn{gigabytes} (@acronym{GB}) of @acronym{RAM}.  See @ref{Tuning
Memory Usage} for details.

Note that Enfuse must have been compiled with the image-cache feature
for this option to be effective.  Find out about extra features with
@code{enfuse --version --verbose}.

@item --no-ciecam
@opindex --no-ciecam
@cindex color appearance model
@cindex @acronym{CIECAM02}
Disable the use of the @acronym{CIECAM02} color appearance model for
blending colors.

See option@tie{}@option{--ciecam} for details.  Also see @ref{Color
Profiles}.
@end table


@node Fusion Options
@section Fusion Options
@cindex options, fusion

Fusion options define the proportion to which each input image's pixel
contributes to the output image.

@table @code
@item --contrast-weight=@var{WEIGHT}
@opindex --contrast-weight
@cindex weight, local contrast

Sets the relative @var{WEIGHT} of high local-contrast pixels.

Valid range: @value{src::minimum-weight-contrast} @leq{} @var{WEIGHT}
@leq{} @value{src::maximum-weight-contrast}.

Default: @value{src::default-weight-contrast}.

See @ref{Local Contrast Weighting} and @ref{Expert Options, Option
contrast-window-size}.

@item --entropy-weight=@var{WEIGHT}
@opindex --entropy-weight
@cindex weight, entropy

Sets the relative @var{WEIGHT} of high local entropy pixels.

Valid range: @value{src::minimum-weight-entropy} @leq{} @var{WEIGHT}
@leq{} @value{src::maximum-weight-entropy}.

Default: @value{src::default-weight-entropy}.

See @ref{Local Entropy Weighting} and @ref{Expert Options, Options
entropy-window-size and entropy-cutoff}.

@item --exposure-weight=@var{WEIGHT}
@opindex --exposure-weight
@cindex weight, exposure

Sets the relative @var{WEIGHT} of the well-exposedness criterion.
Increasing this weight relative to the others will make well-exposed
pixels contribute more to the final output.

Valid range: @value{src::minimum-weight-exposure} @leq{} @var{WEIGHT}
@leq{} @value{src::maximum-weight-exposure}.

Default: @value{src::default-weight-exposure}.

@xref{Exposure Weighting}.

@item --exposure-mu=@var{MEAN}
@opindex --exposure-mu

Set the @var{MEAN} (this is, the center) of the Gaussian exposure
weight curve.

Valid range: @value{src::minimum-exposure-mu} @leq{} @var{MEAN}
@leq{} @value{src::maximum-exposure-mu}.

Default: @value{src::default-exposure-mu}.

Use this option to fine-tune exposure weighting (@pxref{Exposure
Weighting}).

@item --exposure-sigma=@var{STD-DEV}
@opindex --exposure-sigma

Standard deviation @var{STD-DEV} of the Gaussian exposure weight
curve.  Low numbers give less weight to pixels that are far from
@option{--wMu} and vice versa.

Valid range: @var{STD-DEV} @geq{} @value{src::minimum-exposure-sigma}.

Default: @value{src::default-exposure-sigma}.

Use this option to fine-tune exposure weighting (@pxref{Exposure
Weighting}).

@item --saturation-weight=@var{WEIGHT}
@opindex --saturation-weight

Sets the relative @var{WEIGHT} of high-saturation pixels.  Increasing
this weight makes pixels with high saturation contribute more to the
final output.

Valid range: @value{src::minimum-weight-saturation}
@leq{} @var{WEIGHT} @leq{} @value{src::maximum-weight-saturation}.

Default: @value{src::default-weight-saturation}.

Saturation weighting is only defined for color images.
@xref{Saturation Weighting}.
@end table


@node Expert Options
@section Expert Options
@cindex options, expert

Expert options influence the workings of Enfuse that require the user
to read the manual before applying them successfully.

@table @code
@item --contrast-edge-scale=@var{EDGE-SCALE}
@itemx --contrast-edge-scale=@var{EDGE-SCALE}:@var{LCE-SCALE}:@var{LCE-FACTOR}
@opindex --contrast-edge-scale

@cindex Laplacian-of-Gaussian
A non-zero value for @var{EDGE-SCALE} switches on the
Laplacian-of-Gaussian (@acronym{LoG}) edge detection algorithm.
@var{EDGE-SCALE} is the radius of the Gaussian used in the search for
edges.  Default: @value{src::default-edge-scale}@dmn{pixels}.

A positive @var{LCE-SCALE} turns on local contrast enhancement
(@acronym{LCE}) before the @acronym{LoG} edge detection.
@var{LCE-SCALE} is the radius of the Gaussian used in the enhancement
step, @var{LCE-FACTOR} is the weight factor (``strength'').

@var{enhanced} = (1 + @var{LCE-FACTOR}) @classictimes{} @var{original}
@minus{} @var{LCE-FACTOR} @classictimes{} Gaussian@/Smooth(@var{original},
@var{LCE-SCALE}).

@var{LCE-SCALE} defaults to @value{src::default-lce-scale} pixels and
@var{LCE-FACTOR} defaults to @value{src::default-lce-factor}.  Append
@samp{%} to @var{LCE-SCALE} to specify the radius as a percentage of
@var{EDGE-SCALE}.  Append @samp{%} to @var{LCE-FACTOR} to specify the
weight as a percentage.

@item --contrast-min-curvature=@var{CURVATURE}
@opindex --contrast-min-curvature

Define the minimum @var{CURVATURE} for the @acronym{LoG} edge
detection.  Default: @value{src::default-minimum-curvature}.  Append a
@samp{%} to specify the minimum curvature relative to maximum pixel
value in the source image (for example 255 or 65535).

A positive value makes Enfuse use the local contrast data (controlled
with @option{--contrast-window-size}) for curvatures less than
@var{CURVATURE} and @acronym{LoG} data for values above it.

A negative value truncates all curvatures less than
@minus{}@var{CURVATURE} to zero.  Values above @var{CURVATURE} are
left unchanged.  This effectively suppresses weak edges.

@item --contrast-window-size=@var{SIZE}
@opindex --contrast-window-size

Set the window @var{SIZE} for local contrast analysis.  The window
will be a square of @var{SIZE}@classictimes{}@/@var{SIZE} pixels.  If
given an even @var{SIZE}, Enfuse will automatically use the next odd
number.

For contrast analysis @var{SIZE} values larger than 5 might result in
a blurry composite image.  Values of 3 and 5 have given good results
on focus stacks.

Valid range: @var{SIZE} @geq{} @value{src::minimum-contrast-window-size}.

Default: @value{src::default-contrast-window-size}@dmn{pixels}.

See also @ref{Fusion Options, Option --contrast-weight} and
@option{--hard-mask} below.

@item --entropy-cutoff=@var{LOWER-CUTOFF}
@itemx --entropy-cutoff=@var{LOWER-CUTOFF}:@var{UPPER-CUTOFF}
@opindex --entropy-cutoff

The first form defines the lower cutoff value below which pixels are
treated as pure black when calculating the local entropy.  The second
form also defines the upper cutoff value above which pixels are
treated as pure white.

For color images @var{LOWER-CUTOFF} and @var{UPPER-CUTOFF} are applied
separately and independently to each channel.

Defaults: @value{src::default-entropy-lower-cutoff} for
@var{LOWER-CUTOFF} and @value{src::default-entropy-upper-cutoff} for
@var{UPPER-CUTOFF}, that is, all pixels' values are taken into
account.  Append a @samp{%} to specify the cutoff relative to maximum
pixel value in the source image (for example 255 or 65535).
@ref{Figure:entropy-cutoff} shows an example.

@float Figure,Figure:entropy-cutoff
@vimage{entropy-cutoff}

@caption{Linear lightness@tie{}@var{Y} in comparison with an entropy-cutoff function for @var{LOWER-CUTOFF} = 5% and @var{UPPER-CUTOFF} = 90%, which are rather extreme values.  Please note that we have shifted the original lightness curve up and the cut-off curve down by a very small @var{Offset} to emphasize that the proportional part of @var{Y} remains unaltered under the cut-off operation.}

@shortcaption{Entropy cutoff function}
@end float

Note that a high @var{LOWER-CUTOFF} value lightens the resulting
image, as dark (and presumably noisy) pixels are averaged with
@emph{equal} weights.  With @samp{--entropy-cutoff=0}, the default, on
the other hand, ``noise'' might be interpreted as high entropy and the
noisy pixels get a high weight, which in turn renders the resulting
image darker.  Analogously, a low @var{UPPER-CUTOFF} darkens the
output image.

@item --entropy-window-size=@var{SIZE}
@opindex --entropy-window-size

Window @var{SIZE} for local entropy analysis.  The window will be a
square of @var{SIZE}@classictimes{}@/@var{SIZE} pixels.

In the entropy calculation @var{SIZE} values of 3 to 7 yield an
acceptable compromise of the locality of the information and the
significance of the local entropy value itself.

Valid range: @var{SIZE} @geq{} @value{src::minimum-entropy-window-size}.

Default: @value{src::default-entropy-window-size}@dmn{pixels}.

If given an even @var{SIZE} Enfuse will automatically use the next odd
number.

@item --exposure-cutoff=@var{LOWER-CUTOFF}
@itemx --exposure-cutoff=@var{LOWER-CUTOFF}:@var{UPPER-CUTOFF}
@itemx --exposure-cutoff=@var{LOWER-CUTOFF}:@var{UPPER-CUTOFF}:@var{LOWER-PROJECTOR}:@var{UPPER-PROJECTOR}
@opindex --exposure-cutoff

The first form sets the weight for all pixels below the lower cutoff
to zero.  The second form sets the lower cutoff and the upper cutoff
at the same time.  For color images the values of @var{LOWER-CUTOFF}
and @var{UPPER-CUTOFF} refer to the gray-scale projection as selected
with the option @option{--gray-projector}.

The impact of this option is similar, but not identical to
transforming @emph{all} input images with
@uref{http://@/www.imagemagick.org/, ImageMagick's} @command{convert}
(@pxref{Helpful Programs}) prior to fusing with the following
commands.

@example
@group
# First form
convert IMAGE \
        \( +clone -threshold LOWER-CUTOFF \) \
        -compose copy_opacity -composite \
        MASKED-IMAGE
@end group

@group
# Second form
convert IMAGE \
        \( \
            \( IMAGE -threshold LOWER-CUTOFF \) \
            \( IMAGE -threshold UPPER-CUTOFF -negate \) \
            -compose multiply -composite \
        \) \
        -compose copy_opacity -composite \
        MASKED-IMAGE
@end group
@end example

(Transforming some or all input images as shown in the above examples
gives the user more flexibility because the thresholds can be chosen
for each image individually.)

The third form specifies projection operators as in
option@tie{}@option{--gray-projector} for the @var{LOWER-CUTOFF} and
@var{UPPER-CUTOFF} thresholds.

This option can be helpful if the user wants to exclude underexposed
or overexposed pixels from the fusing process in @emph{all} of the
input images.  The values of @var{LOWER-CUTOFF} and @var{UPPER-CUTOFF}
as well as the gray-scale projector determine which pixels are
considered ``underexposed'' or ``overexposed''.  As any change of the
exposure-weight curve this option changes the brightness of the
resulting image: increasing @var{LOWER-CUTOFF} lightens the final
image and lowering @var{UPPER-CUTOFF} darkens it.

Defaults: @value{src::default-exposure-lower-cutoff} for
@var{LOWER-CUTOFF} and @value{src::default-exposure-upper-cutoff} for
@var{UPPER-CUTOFF}, that is, all pixels' values are weighted according
to the ``uncut'' exposure-weight curve.

Append a @samp{%} to specify the cutoff relative to the maximum pixel
value in the source image (for example 255 or 65535).

@ref{Figure:exposure-cutoff} shows an example.

The gray-scale projectors @var{LOWER-PROJECTOR} and
@var{UPPER-PROJECTOR} default to
@samp{@value{src::default-exposure-lower-cutoff-projector}} and
@samp{@value{src::default-exposure-upper-cutoff-projector}}, which are
usually the best choices for effective cutoff operations on the
respective ends.

@float Figure,Figure:exposure-cutoff
@vimage{exposure-cutoff}

@caption{Exposure weight, a Gaussian with @var{Mu} = 0.5 and @var{Sigma} = 0.2 submitted to an exposure-cutoff of @var{LOWER-CUTOFF} = 5% and @var{UPPER-CUTOFF} = 97%.}

@shortcaption{Exposure cutoff function}
@end float

Note that the application of the respective cutoffs is completely
independent of the actual shape of the exposure weight function.

If a set of images stubbornly refuses to ``react'' to this option,
look at their histograms to verify the cutoff actually falls into
populated ranges of the histograms.  In the absence of an image
manipulation program like @uref{http://@/www.gimp.org/, The Gimp},
@uref{http://@/www.imagemagick.org/, ImageMagick} (@pxref{Helpful
Programs}) can be used to generate
@uref{http://@/www.imagemagick.org/@/Usage/@/files/@/#histogram,
histograms}, like, for example,

@example
@group
convert -define histogram:unique-colors=false \
        IMAGE histogram:- | \
    display
@end group
@end example

@item --gray-projector=@var{PROJECTOR}
@opindex --gray-projector
@cindex gray projector

Use gray projector@tie{}@var{PROJECTOR} for conversion of
@acronym{RGB} images to grayscale:
@ifinfo
@math{(R, G, B) --> Y.}
@end ifinfo
@html
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
    <mrowinline>
        <mfencedinline>
            <mi>R</mi>
            <mi>G</mi>
            <mi>B</mi>
        </mfencedinline>
        <mo>&rightarrow;</mo>
        <mi>Y</mi>
        <mtext>.</mtext>
    </mrowinline>
</mathinline>
@end html
@tex
$(R, G, B) \rightarrow Y.$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:lambda>
            <mml:bvar>
                <mml:vector>
                    <mml:ci>R</mml:ci>
                    <mml:ci>G</mml:ci>
                    <mml:ci>B</mml:ci>
                </mml:vector>
            </mml:bvar>
            <mml:ci>Y</mml:ci>
        </mml:lambda>
    </mml:math>
</informalequation>
@end docbook

In version@tie{}@value{VERSION} of Enfuse, the option is effective for
exposure weighting and local contrast weighting.  Default:
@samp{average}.

Valid values for @var{PROJECTOR} are:

@table @code
@item anti-value
@cindex gray projector, @samp{anti-value}
@cindex @samp{anti-value} gray projector
Do the opposite of the @samp{value} projector: take the minimum of all
color channels.
@ifinfo
@display
@math{Y = min(R, G, B)}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mi>Y</mi>
        <mo>=</mo>
        <mrow>
            <mo>min</mo>
            <mo>&ApplyFunction;</mo>
            <mfenced>
                <mi>R</mi>
                <mi>G</mi>
                <mi>B</mi>
            </mfenced>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    Y = \min(R, G, B)
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:ci>Y</mml:ci>
            <mml:apply>
                <mml:min/>
                <mml:ci>R</mml:ci>
                <mml:ci>G</mml:ci>
                <mml:ci>B</mml:ci>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

This projector can be useful when exposure weighing while employing a
lower cutoff (see option@tie{}@option{--exposure-cutoff}) to reduce
the noise in the fused image.

@item average
@cindex gray projector, @samp{average}
@cindex @samp{average} gray projector
Average red, green, and blue channel with equal weights.  This is the
default, and it often is a good projector for @math{gamma = 1} data.
@ifinfo
@display
@math{Y = (R + G + B) / 3}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mi>Y</mi>
        <mo>=</mo>
        <mfrac>
            <mrow>
                <mi>R</mi>
                <mo>+</mo>
                <mi>G</mi>
                <mo>+</mo>
                <mi>B</mi>
            </mrow>
            <mn>3</mn>
        </mfrac>
    </mrow>
</math>
@end html
@tex
$$
    Y = {R + G + B \over 3}
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:ci>Y</mml:ci>
            <mml:apply other='display="scriptstyle"'>
                <mml:divide/>
                <mml:apply>
                    <mml:plus/>
                    <mml:ci>R</mml:ci>
                    <mml:ci>G</mml:ci>
                    <mml:ci>B</mml:ci>
                </mml:apply>
                <mml:cn>3</mml:cn>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@item channel-mixer:@var{RED-WEIGHT}:@var{GREEN-WEIGHT}:@var{BLUE-WEIGHT}
@cindex gray projector, @samp{channel-mixer}
@cindex @samp{channel-mixer} gray projector
Weight the channels as given.
@ifinfo
@display
@math{Y = RED-WEIGHT * R + GREEN-WEIGHT * G + BLUE-WEIGHT * B}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mi>Y</mi>
        <mo>=</mo>
        <mrow>
            <mi mathvariant="italic">RED-WEIGHT</mi>
            <mo>&times;</mo>
            <mi>R</mi>
        </mrow>
        <mo>+</mo>
        <mrow>
            <mi mathvariant="italic">GREEN-WEIGHT</mi>
            <mo>&times;</mo>
            <mi>G</mi>
        </mrow>
        <mo>+</mo>
        <mrow>
            <mi mathvariant="italic">BLUE-WEIGHT</mi>
            <mo>&times;</mo>
            <mi>B</mi>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    \eqalign{Y \quad = \quad
        & \mathit{RED-WEIGHT} \times R \; + \cr
        & \mathit{GREEN-WEIGHT} \times G \; + \cr
        & \mathit{BLUE-WEIGHT} \times B \cr}
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:ci>Y</mml:ci>
            <mml:apply>
                <mml:plus/>
                <mml:apply>
                    <mml:times/>
                    <mml:csymbol>
                        <mml:mi mathvariant="italic">RED-WEIGHT</mml:mi>
                    </mml:csymbol>
                    <mml:ci>R</mml:ci>
                </mml:apply>
                <mml:apply>
                    <mml:times/>
                    <mml:csymbol>
                        <mml:mi mathvariant="italic">GREEN-WEIGHT</mml:mi>
                    </mml:csymbol>
                    <mml:ci>G</mml:ci>
                </mml:apply>
                <mml:apply>
                    <mml:times/>
                    <mml:csymbol>
                        <mml:mi mathvariant="italic">BLUE-WEIGHT</mml:mi>
                    </mml:csymbol>
                    <mml:ci>B</mml:ci>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

The weights are automatically normalized to one, so

@example
--gray-projector=channel-mixer:0.25:0.5:0.25
--gray-projector=channel-mixer:1:2:1
--gray-projector=channel-mixer:25:50:25
@end example

all define the same mixer configuration.

The three weights @var{RED-WEIGHT}, @var{GREEN-WEIGHT}, and
@var{BLUE-WEIGHT} define the relative weight of the respective color
channel.  The sum of all weights is normalized to one.

@item l-star
@cindex gray projector, @samp{l-star}
@cindex @samp{l-star} gray projector
@cindex RGB-L*a*b* conversion
@cindex conversion, RGB-L*a*b*
Use the L-channel of the L*a*b*-conversion of the image as its
grayscale representation.  This is a useful projector for gamma = 1
data.  It reveals minute contrast variations even in the shadows and
the highlights.  This projector is computationally expensive.  Compare
with @samp{pl-star}, which is intended for gamma-corrected images.

See @uref{http://@/en.wikipedia.org/@/wiki/@/Lab_@/color_@/space,
Wikipedia} for a detailed description of the @acronym{Lab}@tie{}color
space.

@item lightness
@cindex gray projector, @samp{lightness}
@cindex @samp{lightness} gray projector
Compute the lightness of each @acronym{RGB} pixel as in an
Hue-Saturation-Lightness (@acronym{HSL}) conversion of the image.
@ifinfo
@display
@math{Y = (max(R, G, B) + min(R, G, B)) / 2}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mi>Y</mi>
        <mo>=</mo>
        <mfrac>
            <mrow>
                <mrow>
                    <mo>max</mo>
                    <mo>&ApplyFunction;</mo>
                    <mfenced>
                        <mi>R</mi>
                        <mi>G</mi>
                        <mi>B</mi>
                    </mfenced>
                </mrow>
                <mo>+</mo>
                <mrow>
                    <mo>min</mo>
                    <mo>&ApplyFunction;</mo>
                    <mfenced>
                        <mi>R</mi>
                        <mi>G</mi>
                        <mi>B</mi>
                    </mfenced>
                </mrow>
            </mrow>
            <mn>2</mn>
        </mfrac>
    </mrow>
</math>
@end html
@tex
$$
    Y = {\max(R, G, B) + \min(R, G, B) \over 2}
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:ci>Y</mml:ci>
            <mml:apply>
                <mml:divide/>
                <mml:apply>
                    <mml:plus/>
                    <mml:apply>
                        <mml:max/>
                        <mml:ci>R</mml:ci>
                        <mml:ci>G</mml:ci>
                        <mml:ci>B</mml:ci>
                    </mml:apply>
                    <mml:apply>
                        <mml:min/>
                        <mml:ci>R</mml:ci>
                        <mml:ci>G</mml:ci>
                        <mml:ci>B</mml:ci>
                    </mml:apply>
                </mml:apply>
                <mml:cn>2</mml:cn>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@item luminance
@cindex gray projector, @samp{luminance}
@cindex @samp{luminance} gray projector
Use the weighted average of the @acronym{RGB} pixel's channels as
defined by @acronym{CIE} (``Commission Internationale de
l'@'Eclairage'') and the @acronym{JPEG} standard.
@ifinfo
@display
@math{Y = 0.30 * R + 0.59 * G + 0.11 * B}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mi>Y</mi>
        <mo>=</mo>
        <mrow>
            <mn>0.30</mn>
            <mo>&times;</mo>
            <mi>R</mi>
        </mrow>
        <mo>+</mo>
        <mrow>
            <mn>0.59</mn>
            <mo>&times;</mo>
            <mi>G</mi>
        </mrow>
        <mo>+</mo>
        <mrow>
            <mn>0.11</mn>
            <mo>&times;</mo>
            <mi>B</mi>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    Y = 0.30 \times R + 0.59 \times G + 0.11 \times B
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:ci>Y</mml:ci>
            <mml:apply>
                <mml:plus/>
                <mml:apply>
                    <mml:times/>
                    <mml:cn type="real">0.30</mml:cn>
                    <mml:ci>R</mml:ci>
                </mml:apply>
                <mml:apply>
                    <mml:times/>
                    <mml:cn type="real">0.59</mml:cn>
                    <mml:ci>G</mml:ci>
                </mml:apply>
                <mml:apply>
                    <mml:times/>
                    <mml:cn type="real">0.11</mml:cn>
                    <mml:ci>B</mml:ci>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@item pl-star
@cindex gray projector, @samp{pl-star}
@cindex @samp{pl-star} gray projector
@cindex RGB'-L*a*b* conversion
@cindex conversion, RGB'-L*a*b*
Use the L-channel of the L*a*b*-conversion of the image as its
grayscale representation.  This is a useful projector for
gamma-corrected data.  It reveals minute contrast variations even in
the shadows and the highlights.  This projector is computationally
expensive.  Compare with @samp{l-star}, which is intended for gamma =
1 images.

See @uref{http://@/en.wikipedia.org/@/wiki/@/Lab_@/color_@/space,
Wikipedia} for a detailed description of the @acronym{Lab}@tie{}color
space.

@item value
@cindex gray projector, @samp{value}
@cindex @samp{value} gray projector
Take the Value-channel of the Hue-Saturation-Value (@acronym{HSV})
conversion of the image.
@ifinfo
@display
@math{Y = max(R, G, B)}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mi>Y</mi>
        <mo>=</mo>
        <mrow>
            <mo>max</mo>
            <mo>&ApplyFunction;</mo>
            <mfenced>
                <mi>R</mi>
                <mi>G</mi>
                <mi>B</mi>
            </mfenced>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    Y = \max(R, G, B)
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:ci>Y</mml:ci>
            <mml:apply>
                <mml:max/>
                <mml:ci>R</mml:ci>
                <mml:ci>G</mml:ci>
                <mml:ci>B</mml:ci>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook
@end table

@item --hard-mask
@opindex --hard-mask

Force hard blend masks on the finest scale.  This is the opposite flag
of @option{--soft-mask}.

This blending mode avoids averaging of fine details (only) at the
expense of increasing the noise.  However it considerably improves the
sharpness of focus stacks.  Blending with hard masks has only proven
useful with focus stacks.

See also @ref{Fusion Options, Option --contrast-weight} and
@option{--contrast-window-size} above.

@item --load-masks
@itemx --load-masks=@var{SOFT-MASK-TEMPLATE}
@itemx --load-masks=@var{SOFT-MASK-TEMPLATE}:@var{HARD-MASK-TEMPLATE}
@opindex --load-masks

Load masks from images instead of computing them.

The masks have to be a grayscale images.

@cindex mask, loading
First form: Load all soft-weight masks from files that were previously
saved with option@tie{}@option{--save-masks}.  If
option@tie{}@option{--hard-mask} is effective only load hard masks.
The defaults are @file{@value{src::default-soft-mask-template}} and
@file{@value{src::default-hard-mask-template}}.
@cindex filename template
@cindex mask, filename template
In the second form, @var{SOFT-MASK-TEMPLATE} defines the names of the
soft-mask files.  In the third form, @var{HARD-MASK-TEMPLATE}
additionally defines the names of the hard-mask files.  See
option@tie{}@option{--save-masks} below for the description of mask
templates.

Options@tie{}@option{--load-masks} and @option{--save-masks} are
mutually exclusive.

@item --save-masks
@itemx --save-masks=@var{SOFT-MASK-TEMPLATE}
@itemx --save-masks=@var{SOFT-MASK-TEMPLATE}:@var{HARD-MASK-TEMPLATE}
@opindex --save-masks
@cindex mask, save
@cindex save mask
Save the generated weight masks to image files.

First form: Save all soft-weight masks in files.  If
option@tie{}@option{--hard-mask} is effective also save the hard masks.
The defaults are @file{@value{src::default-soft-mask-template}} and
@file{@value{src::default-hard-mask-template}}.
@cindex filename template
@cindex mask, filename template
In the second form, @var{SOFT-MASK-TEMPLATE} defines the names of the
soft-mask files.  In the third form, @var{HARD-MASK-TEMPLATE}
additionally defines the names of the hard-mask files.

@cindex save mask, only
@cindex only save mask
Enfuse will stop after saving all masks unless
option@tie{}@option{--output} is given, too.  With both options given,
this is, @option{--save-masks} and @option{--output}, Enfuse saves all
masks and then proceeds to fuse the output image.

Both @var{SOFT-MASK-TEMPLATE} and @var{HARD-MASK-TEMPLATE} define
templates that are expanded for each mask file.  In a template a
percent sign (@samp{%}) introduces a variable part.  All other
characters are copied literally.  Lowercase letters refer to the name
of the respective input file, whereas uppercase ones refer to the name
of the output file (@pxref{Common Options}).
@ref{Table:mask-template-characters} lists all variables.

A fancy mask filename template could look like this:

@example
%D/soft-mask-%02n-%f.viff
@end example

It puts the mask files into the same directory as the output file
(@samp{%D}), generates a two-digit index (@samp{%02n}) to keep the
mask files nicely sorted, and decorates the mask filename with the
name of the associated input file (@samp{%f}) for easy recognition.

@item --soft-mask
@opindex --soft-mask

Consider all masks when fusing.  This is the default.
@end table

@c The extra <para>s fix another stupid Texinfo problem with DocBook.
@docbook
<para>
@end docbook
Options@tie{}@option{--save-masks} and @option{--load-masks} are
mutually exclusive.
@docbook
</para>
@end docbook

@page

@include mask-template-characters.texi

@node Option Delimiters
@section Option Delimiters
@cindex option delimiters
@cindex delimiters, option

Enfuse allows the arguments supplied to the program's options to be
separated by different separators.  The online documentation and this
manual, however, exclusively use the colon @samp{:} in every syntax
definition and in all examples.

@need 500
@noindent
@strong{Numeric Arguments}

Valid delimiters are the the semicolon @samp{;}, the colon @samp{:},
and the slash @samp{/}.  All delimiters may be mixed within any
option that takes numeric arguments.

@noindent
Examples:

@table @samp
@item --contrast-edge-scale=0.667:6.67:3.5
Separate all arguments with colons.

@item --contrast-edge-scale=0.667;6.67;3.5
Use semi-colons.

@item --contrast-edge-scale=0.667;6.67/3.5
Mix semicolon and slash in weird ways.

@item --entropy-cutoff=3%/99%
All delimiters also work in conjunction with percentages.

@item --gray-projector=channel-mixer:3/6/1
Separate arguments with a colon and two slashes.

@item --gray-projector=channel-mixer/30;60:10
Go wild and Enfuse will understand.
@end table

@need 500
@noindent
@strong{Filename Arguments}

Here, the accepted delimiters are @samp{,}, @samp{;}, and @samp{:}.
Again, all delimiters may be mixed within any option that has filename
arguments.

@noindent
Examples:

@table @samp
@item --save-masks=soft-mask-%03i.tif:hard-mask-03%i.tif
Separate all arguments with colons.

@item --save-masks=%d/soft-%n.tif,%d/hard-%n.tif
Use a comma.
@end table


@node Color Profiles
@chapter Color Profiles
@cindex profile, @acronym{ICC}
@cindex @acronym{ICC} profile
@cindex color profile

@include color-profiles.texi


@node Weighting Functions
@chapter Weighting Functions
@cindex weighting functions

As has been noted in the Overview (@pxref{Overview}), Enfuse supports
four different types of weighting.  The following subsections describe
the concept of weighting and all weighting functions in detail.

@menu
* Weighting Pixels::            General concept of weighting pixels
* Exposure Weighting::          Weighting by exposure
* Saturation Weighting::        Weighting by saturation
* Local Contrast Weighting::    Weighting by local contrast
* Local Entropy Weighting::     Weighting by local entropy
@end menu


@node Weighting Pixels
@section Weighting Pixels
@cindex weighting, general concept of

Image fusion maps each pixel@tie{}@math{P(i, x, y)} of every input
image @math{i} to a single pixel@tie{}@math{Q(x, y)} in the output
image:
@ifinfo
@display
@math{P(i, x, y) --> Q(x, y),}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mi>P</mi>
            <mfenced>
                <mi>i</mi>
                <mi>x</mi>
                <mi>y</mi>
            </mfenced>
        </mrow>
        <mo>&rightarrow;</mo>
        <mrow>
            <mi>Q</mi>
            <mfenced>
                <mi>x</mi>
                <mi>y</mi>
            </mfenced>
        </mrow>
        <mtext>,</mtext>
    </mrow>
</math>
@end html
@tex
$$
    P(i, x, y) \rightarrow Q(x, y),
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:lambda>
            <mml:bvar>
                <mml:apply>
                    <mml:ci>P</mml:ci>
                    <mml:ci>i</mml:ci>
                    <mml:ci>x</mml:ci>
                    <mml:ci>y</mml:ci>
                </mml:apply>
            </mml:bvar>
            <mml:apply>
                <mml:ci>Q</mml:ci>
                <mml:ci>x</mml:ci>
                <mml:ci>y</mml:ci>
            </mml:apply>
        </mml:lambda>
    </mml:math>
</informalequation>
@end docbook

@noindent
where @math{x} runs from 1 to the common width of the images, @math{y}
from 1 to the common height, and @math{i} from 1 to the number of
input images@tie{}@math{n}.

@macro equationW{}
@ifnotdocbook
@ifnottex
(W)
@end ifnottex
@end ifnotdocbook
@tex
(W)%
@end tex
@docbook
<xref linkend="equ:pixel-weighting-function"/>
@end docbook
@end macro

Enfuse allows for weighting the contribution of each @math{P(i, x, y)}
to the final @math{Q(x, y)}:
@ifinfo
@display
@math{w(P(1, x, y)) * P(1, x, y) +
... +
w(P(n, x, y)) * P(n, x, y)
--> Q(x, y),}@w{                                                  }@equationW{}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mi>w</mi>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mrow>
                    <mi>P</mi>
                    <mfenced>
                        <mi>1</mi>
                        <mi>x</mi>
                        <mi>y</mi>
                    </mfenced>
                </mrow>
                <mo>)</mo>
            </mrow>
            <mo>&times;</mo>
            <mrow>
                <mi>P</mi>
                <mfenced>
                    <mi>1</mi>
                    <mi>x</mi>
                    <mi>y</mi>
                </mfenced>
            </mrow>
            <mo>+</mo>
            <mo>...</mo>
            <mo>+</mo>
            <mi>w</mi>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mrow>
                    <mi>P</mi>
                    <mfenced>
                        <mi>n</mi>
                        <mi>x</mi>
                        <mi>y</mi>
                    </mfenced>
                </mrow>
                <mo>)</mo>
            </mrow>
            <mo>&times;</mo>
            <mrow>
                <mi>P</mi>
                <mfenced>
                    <mi>n</mi>
                    <mi>x</mi>
                    <mi>y</mi>
                </mfenced>
            </mrow>
        </mrow>
        <mo>&rightarrow;</mo>
        <mrow>
            <mi>Q</mi>
            <mfenced>
                <mi>i</mi>
                <mi>x</mi>
                <mi>y</mi>
            </mfenced>
        </mrow>
        <mtext>,</mtext>
        <mspace width="4em"/>
        <mtext>@equationW{}</mtext>
    </mrow>
</math>
@end html
@tex
$$
    w(P(1, x, y)) P(1, x, y) + \ldots + w(P(n, x, y)) P(n, x, y)
    \rightarrow
    Q(x, y),\hskip4em\hbox{@equationW{}}
$$
@end tex
@docbook
<equation id="equ:pixel-weighting-function">
    <title>Pixel Weighting Function</title>
    <mml:math>
        <mml:lambda>
            <mml:bvar>
                <mml:apply>
                    <mml:plus/>
                    <mml:apply>
                        <mml:times/>
                        <mml:apply>
                            <mml:ci>w</mml:ci>
                            <mml:apply>
                                <mml:ci>P</mml:ci>
                                <mml:cn>1</mml:cn>
                                <mml:ci>x</mml:ci>
                                <mml:ci>y</mml:ci>
                            </mml:apply>
                        </mml:apply>
                        <mml:apply>
                            <mml:ci>P</mml:ci>
                            <mml:cn>1</mml:cn>
                            <mml:ci>x</mml:ci>
                            <mml:ci>y</mml:ci>
                        </mml:apply>
                    </mml:apply>
                    <mml:mo>...</mml:mo>
                    <mml:apply>
                        <mml:times/>
                        <mml:apply>
                            <mml:ci>w</mml:ci>
                            <mml:apply>
                                <mml:ci>P</mml:ci>
                                <mml:ci>n</mml:ci>
                                <mml:ci>x</mml:ci>
                                <mml:ci>y</mml:ci>
                            </mml:apply>
                        </mml:apply>
                        <mml:apply>
                            <mml:ci>P</mml:ci>
                            <mml:ci>n</mml:ci>
                            <mml:ci>x</mml:ci>
                            <mml:ci>y</mml:ci>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
            </mml:bvar>
            <mml:apply>
                <mml:ci>Q</mml:ci>
                <mml:ci>x</mml:ci>
                <mml:ci>y</mml:ci>
            </mml:apply>
        </mml:lambda>
    </mml:math>
</equation>
@end docbook

@noindent
where

@itemize
@item
each @math{w} is non-negative to yield a physical intensity and

@item
the sum of all @math{w} is one to leave the total intensity unchanged.
@end itemize

@noindent
The pixel weights@tie{}@math{w} themselves are weighted sums with the
same constraints
@ifinfo
@display
@math{w(P) = w_exp * f_exp(P) +
       w_sat * f_sat(P) +
       w_cont * f_cont(P, r_cont) +
       w_ent * f_ent(P, r_ent),}
@end display

@noindent
where we have abbreviated @math{P(i, x, y)} to @math{P} for
simplicity.  The user defines the constants@tie{}@math{w_exp},
@math{w_sat}, @math{w_cont}, and @math{w_ent} with the options
@option{--exposure-weight}, @option{--saturation-weight},
@option{--contrast-weight}, and @option{--entropy-weight}.  The
functions@tie{}@math{f_exp}, @math{f_sat}, @math{f_cont}, and
@math{f_ent} along with the window sizes@tie{}@math{r_cont} and
@math{r_ent} are explained in the next sections.
@end ifinfo
@html
</p>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mtable>
        <mtr>
            <mtd>
                <mi>w</mi>
                <mo>&ApplyFunction;</mo>
                <mrow>
                    <mo>(</mo>
                    <mi>P</mi>
                    <mo>)</mo>
                </mrow>
            </mtd>
            <mtd>
                <mo>=</mo>
            </mtd>
            <mtd>
                <msub>
                    <mi>w</mi>
                    <mtext>exp</mtext>
                </msub>
                <mo>&times;</mo>
                <mrow>
                    <msub>
                        <mi>f</mi>
                        <mtext>exp</mtext>
                    </msub>
                    <mo>&ApplyFunction;</mo>
                    <mrow>
                        <mo>(</mo>
                        <mi>P</mi>
                        <mo>)</mo>
                    </mrow>
                    <mo>+</mo>
                </mrow>
            </mtd>
        </mtr>
        <mtr>
            <mtd></mtd>
            <mtd></mtd>
            <mtd>
                <msub>
                    <mi>w</mi>
                    <mtext>sat</mtext>
                </msub>
                <mo>&times;</mo>
                <mrow>
                    <msub>
                        <mi>f</mi>
                        <mtext>sat</mtext>
                    </msub>
                    <mo>&ApplyFunction;</mo>
                    <mrow>
                        <mo>(</mo>
                        <mi>P</mi>
                        <mo>)</mo>
                    </mrow>
                    <mo>+</mo>
                </mrow>
            </mtd>
        </mtr>
        <mtr>
            <mtd></mtd>
            <mtd></mtd>
            <mtd>
                <msub>
                    <mi>w</mi>
                    <mtext>cont</mtext>
                </msub>
                <mo>&times;</mo>
                <mrow>
                    <msub>
                        <mi>f</mi>
                        <mtext>cont</mtext>
                    </msub>
                    <mo>&ApplyFunction;</mo>
                    <mfenced>
                        <mi>P</mi>
                        <msub>
                            <mi>r</mi>
                            <mtext>cont</mtext>
                        </msub>
                    </mfenced>
                </mrow>
                <mo>+</mo>
            </mtd>
        </mtr>
        <mtr>
            <mtd></mtd>
            <mtd></mtd>
            <mtd>
                <msub>
                    <mi>w</mi>
                    <mtext>ent</mtext>
                </msub>
                <mo>&times;</mo>
                <mrow>
                    <msub>
                        <mi>f</mi>
                        <mtext>ent</mtext>
                    </msub>
                    <mo>&ApplyFunction;</mo>
                    <mfenced>
                        <mi>P</mi>
                        <msub>
                            <mi>r</mi>
                            <mtext>ent</mtext>
                        </msub>
                    </mfenced>
                </mrow>
            </mtd>
        </mtr>
    </mtable>
</math>

<p>where we have abbreviated
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<mi>P</mi> <mrowinline> <mo>(</mo> <mi>i</mi> <mo>,</mo> <mi>x</mi> <mo>,</mo>
<mi>y</mi> <mo>)</mo> </mrowinline> </mathinline> to
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<mi>P</mi> </mathinline> for simplicity.  The user defines the
constants&nbsp;<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>w</mi> <mtext>exp</mtext> </msubinline> </mathinline>,
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>w</mi> <mtext>sat</mtext> </msubinline> </mathinline>,
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>w</mi> <mtext>cont</mtext> </msubinline> </mathinline>, and
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>w</mi> <mtext>ent</mtext> </msubinline> </mathinline> with the options
`<tt>--exposure-weight</tt>', `<tt>--saturation-weight</tt>',
`<tt>--contrast-weight</tt>', and `<tt>--entropy-weight</tt>'
respectively.  The
functions&nbsp;<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>f</mi> <mtext>exp</mtext> </msubinline> </mathinline>,
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>f</mi> <mtext>sat</mtext> </msubinline> </mathinline>,
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>f</mi> <mtext>cont</mtext> </msubinline> </mathinline>, and
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>f</mi> <mtext>ent</mtext> </msubinline> </mathinline> along with the window
sizes&nbsp;<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>r</mi> <mtext>cont</mtext> </msubinline> </mathinline> and
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<msubinline> <mi>r</mi> <mtext>ent</mtext> </msubinline> </mathinline> are explained in
the next sections.</p><p>
@end html
@tex
$$
    \eqalign{w(P) \quad = \quad
        & w_{\mathrm{exp}} \; f_{\mathrm{exp}}(P) + \cr
        & w_{\mathrm{sat}} \; f_{\mathrm{sat}}(P) + \cr
        & w_{\mathrm{cont}} \; f_{\mathrm{cont}}(P, r_{\mathrm{cont}}) + \cr
        & w_{\mathrm{ent}} \; f_{\mathrm{ent}}(P, r_{\mathrm{ent}}), \cr}
$$

\noindent where we have abbreviated $P(i, x, y)$ to $P$ for
simplicity.  The user defines the constants~$w_{\mathrm{exp}}$,
$w_{\mathrm{sat}}$, $w_{\mathrm{cont}}$, and $w_{\mathrm{ent}}$ with
the options `{\tt --exposure-weight}', `{\tt --saturation-weight}', `{\tt
--contrast-weight}', and `{\tt --entropy-weight}' respectively.  The
functions~$f_{\mathrm{exp}}$, $f_{\mathrm{sat}}$, $f_{\mathrm{cont}}$,
and $f_{\mathrm{ent}}$ along with the window sizes~$r_{\mathrm{cont}}$
and $r_{\mathrm{ent}}$ are explained in the next sections.
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:ci>w</mml:ci>
                <mml:ci>P</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:plus/>
                <mml:apply>
                    <mml:times/>
                    <mml:csymbol>
                        <mml:msub>
                            <mml:mi>w</mml:mi>
                            <mml:mi mathvariant="normal">exp</mml:mi>
                        </mml:msub>
                    </mml:csymbol>
                    <mml:apply>
                        <mml:csymbol>
                            <mml:msub>
                                <mml:mi>f</mml:mi>
                                <mml:mi mathvariant="normal">exp</mml:mi>
                            </mml:msub>
                        </mml:csymbol>
                        <mml:ci>P</mml:ci>
                    </mml:apply>
                </mml:apply>
                <mml:apply>
                    <mml:times/>
                    <mml:csymbol>
                        <mml:msub>
                            <mml:mi>w</mml:mi>
                            <mml:mi mathvariant="normal">sat</mml:mi>
                        </mml:msub>
                    </mml:csymbol>
                    <mml:apply>
                        <mml:csymbol>
                            <mml:msub>
                                <mml:mi>f</mml:mi>
                                <mml:mi mathvariant="normal">sat</mml:mi>
                            </mml:msub>
                        </mml:csymbol>
                        <mml:ci>P</mml:ci>
                    </mml:apply>
                </mml:apply>
                <mml:apply>
                    <mml:times/>
                    <mml:csymbol>
                        <mml:msub>
                            <mml:mi>w</mml:mi>
                            <mml:mi mathvariant="normal">cont</mml:mi>
                        </mml:msub>
                    </mml:csymbol>
                    <mml:apply>
                        <mml:csymbol>
                            <mml:msub>
                                <mml:mi>f</mml:mi>
                                <mml:mi mathvariant="normal">cont</mml:mi>
                            </mml:msub>
                        </mml:csymbol>
                        <mml:ci>P</mml:ci>
                        <mml:csymbol>
                            <mml:msub>
                                <mml:mi>r</mml:mi>
                                <mml:mi mathvariant="normal">cont</mml:mi>
                            </mml:msub>
                        </mml:csymbol>
                    </mml:apply>
                </mml:apply>

                <mml:apply>
                    <mml:times/>
                    <mml:csymbol>
                        <mml:msub>
                            <mml:mi>w</mml:mi>
                            <mml:mi mathvariant="normal">ent</mml:mi>
                        </mml:msub>
                    </mml:csymbol>
                    <mml:apply>
                        <mml:csymbol>
                            <mml:msub>
                                <mml:mi>f</mml:mi>
                                <mml:mi mathvariant="normal">ent</mml:mi>
                            </mml:msub>
                        </mml:csymbol>
                        <mml:ci>P</mml:ci>
                        <mml:csymbol>
                            <mml:msub>
                                <mml:mi>r</mml:mi>
                                <mml:mi mathvariant="normal">ent</mml:mi>
                            </mml:msub>
                        </mml:csymbol>
                    </mml:apply>
                </mml:apply>

            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>

where we have abbreviated <inlineequation> <mml:math> <mml:apply>
<mml:ci>P</mml:ci> <mml:ci>i</mml:ci> <mml:ci>x</mml:ci>
<mml:ci>y</mml:ci> </mml:apply> </mml:math> </inlineequation> to
<inlineequation> <mml:math> <mml:ci>P</mml:ci> </mml:math>
</inlineequation> for simplicity.  The user defines the
constants&nbsp;<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>w</mml:mi> <mml:mi mathvariant="normal">exp</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation>,
<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>w</mml:mi> <mml:mi mathvariant="normal">sat</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation>,
<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>w</mml:mi> <mml:mi mathvariant="normal">cont</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation>, and
<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>w</mml:mi> <mml:mi mathvariant="normal">ent</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation>, with the
options <literal>--exposure-weight</literal>,
<literal>--saturation-weight</literal>,
<literal>--contrast-weight</literal>, and
<literal>--entropy-weight</literal> respectively.  The
functions&nbsp;<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>f</mml:mi> <mml:mi mathvariant="normal">exp</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation>,
<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>f</mml:mi> <mml:mi mathvariant="normal">sat</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation>,
<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>f</mml:mi> <mml:mi mathvariant="normal">cont</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation>, and
<inlineequation> <mml:math> <mml:csymbol> <mml:msub>
<mml:mi>f</mml:mi> <mml:mi mathvariant="normal">ent</mml:mi>
</mml:msub> </mml:csymbol> </mml:math> </inlineequation> along with
the window sizes&nbsp;<inlineequation> <mml:math> <mml:csymbol>
<mml:msub> <mml:mi>r</mml:mi> <mml:mi
mathvariant="normal">cont</mml:mi> </mml:msub>
</mml:csymbol></mml:math> </inlineequation> and <inlineequation>
<mml:math> <mml:csymbol> <mml:msub> <mml:mi>r</mml:mi> <mml:mi
mathvariant="normal">ent</mml:mi> </mml:msub> </mml:csymbol>
</mml:math> </inlineequation> are explained in the next sections.
@end docbook

@menu
* Weighted Average::            Enfuse's default weighting algorithm
* Disabling Averaging::         ``Super Trouper'' weighting for focus stacks
* Single Criterion Fusing::     Fusing with only one of the criteria
@end menu


@node Weighted Average
@subsection Weighted Average
@cindex weighted average
@cindex average, weighted

By default, Enfuse uses a weighted average, where @emph{each} pixel
contributes as much as its weight demands.  Of course the weights can
be extreme, favoring only a few pixels or even only one pixel in the
input stack.  Extremes are not typical, however.

Equal weights are another extreme that turns @equationW{} into an
arithmetic average.  This is why we sometimes speak of the ``averaging
property'' of this weighting algorithm, like smoothing out noise.


@node Disabling Averaging
@subsection Disabling Averaging: Option@tie{}@option{--hard-mask}
@cindex disabling average
@cindex average, disabling
@opindex --hard-mask

The weighted average computation as described above has proven to be
widely successful with the exception of one special case: focus
stacking (@pxref{Focus Stacks}), where the averaging noticeably
softens the final image.

Use @option{--hard-mask} to switch Enfuse into a different (``Super
Trouper'') weighting mode, where the pixel with the highest weight
wins, this is, gets weight@tie{}one, and all other pixels get the
weight of zero
(@uref{http://@/en.wikipedia.org/@/wiki/@/The_@/Winner_@/Takes_@/It_@/All,,``The
Winner Takes It All.''}).  With @option{--hard-mask} Equation@tie{}@equationW{}
becomes
@ifinfo
@display
@math{P(i, x, y) --> Q(x, y),}
@end display

@noindent
where
@display
@math{w(P(i, x, y)) >= w(P(j, x, y))} for all @math{1 <= j <= n}.
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mrow>
                <mi>P</mi>
                <mfenced>
                    <mi>i</mi>
                    <mi>x</mi>
                    <mi>y</mi>
                </mfenced>
            </mrow>
            <mo>&rightarrow;</mo>
            <mrow>
                <mi>Q</mi>
                <mfenced>
                    <mi>x</mi>
                    <mi>y</mi>
                </mfenced>
            </mrow>
            <mtext>,</mtext>
        </mrow>
        <mtext>&ThickSpace;where&ThickSpace;</mtext>
        <mrow>
            <mi>w</mi>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mi>P</mi>
                <mfenced>
                    <mi>i</mi>
                    <mi>x</mi>
                    <mi>y</mi>
                </mfenced>
                <mo>)</mo>
            </mrow>
            <mo>&ge;</mo>
            <mi>w</mi>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mi>P</mi>
                <mfenced>
                    <mi>j</mi>
                    <mi>x</mi>
                    <mi>y</mi>
                </mfenced>
                <mo>)</mo>
            </mrow>
        </mrow>
        <mtext>&ThickSpace;for all&ThickSpace;</mtext>
        <mrow>
            <mn>1</mn>
            <mo>&le;</mo>
            <mi>j</mi>
            <mo>&le;</mo>
            <mi>n</mi>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    P(i, x, y) \rightarrow Q(x, y),
    \hbox{ where } w(P(i, x, y)) \ge w(P(j, x, y))
    \hbox{ for all } 1 \le j \le n.
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:lambda>
            <mml:bvar>
                <mml:apply>
                    <mml:ci>P</mml:ci>
                    <mml:ci>i</mml:ci>
                    <mml:ci>x</mml:ci>
                    <mml:ci>y</mml:ci>
                </mml:apply>
            </mml:bvar>
            <mml:apply>
                <mml:ci>Q</mml:ci>
                <mml:ci>x</mml:ci>
                <mml:ci>y</mml:ci>
            </mml:apply>
        </mml:lambda>
    </mml:math>
</informalequation>
where
<informalequation>
    <mml:math>
        <mml:apply>
            <mml:forall/>
            <mml:bvar>
                <mml:condition>
                    <mml:reln>
                        <mml:leq/>
                        <mml:cn>1</mml:cn>
                        <mml:ci>j</mml:ci>
                        <mml:ci>n</mml:ci>
                    </mml:reln>
                </mml:condition>
            </mml:bvar>
            <mml:reln>
                <mml:geq/>
                <mml:apply>
                    <mml:ci>w</mml:ci>
                    <mml:apply>
                        <mml:ci>P</mml:ci>
                        <mml:ci>i</mml:ci>
                        <mml:ci>x</mml:ci>
                        <mml:ci>y</mml:ci>
                    </mml:apply>
                </mml:apply>
                <mml:apply>
                    <mml:ci>w</mml:ci>
                    <mml:apply>
                        <mml:ci>P</mml:ci>
                        <mml:ci>j</mml:ci>
                        <mml:ci>x</mml:ci>
                        <mml:ci>y</mml:ci>
                    </mml:apply>
                </mml:apply>
            </mml:reln>
        </mml:apply>
    </mml:math>
</informalequation>
@end docbook

@noindent
Note that this ``averaging'' scheme lacks the nice noise-reduction
property of the weighted average@tie{}@equationW{}, because only a
single input pixel contributes to the output.


@node Single Criterion Fusing
@subsection Single Criterion Fusing
@cindex single criterion fusing
@cindex fusing, single criterion

Enfuse allows the user to weight each pixel of an input image by up to
four different criteria (@pxref{Overview}).  However, it does not
force the user to do so.  For some applications and more often simply
to gain further insight into the weighting and fusing process, looking
at only a single criterion is the preferred way to work.

@cindex active criterion
@cindex criterion, active
The version of Enfuse for which this documentation was prepared, uses
the default weights as stated in @ref{Table:default-weights}.  Notice
that by default @emph{more than one} weight is larger than zero, which
means they are @emph{active}.

@float Table,Table:default-weights
@multitable {Local Contrast} {0.0}
@headitem Criterion  @tab Weight
@item Exposure       @tab @value{src::default-weight-exposure}
@item Saturation     @tab @value{src::default-weight-saturation}
@item Local Contrast @tab @value{src::default-weight-contrast}
@item Local Entropy  @tab @value{src::default-weight-entropy}
@end multitable

@caption{Enfuse's default weights as compiled into version@tie{}@value{VERSION}.}

@shortcaption{Default weights}

@cindex default weights
@cindex weights, default
@end float

To disable a particular criterion set its weight to zero as for
example
@example
enfuse \
    --exposure-weight=1 --saturation-weight=0 \
    --contrast-weight=0 --entropy-weight=0 \
    img_[1-3].png
@end example
instructs Enfuse to consider only the exposure weight.  Combine this
with option@tie{}@option{--save-masks} and it will become clearer how
Enfuse computes the exposure weight for the set of images.

@cindex overpowering criteria
@cindex criteria, overpowering one another
Another problem that can be inspected by fusing with just a single
active criterion and saving the masks is if the weights of one
criterion completely overpower all others.


@node Exposure Weighting
@section Exposure Weighting
@cindex weighting, exposure

Exposure weighting prefers pixels with a luminance@tie{}@math{Y} close
to the center of the normalized, real-valued luminance
interval@tie{}@math{[0, 1]}.

@acronym{RGB}-pixels get converted to luminance using the grayscale
projector given by @option{--gray-@/projector}, which defaults to
@code{average}.  Grayscale pixels are identified with luminance.

In the normalized luminance interval 0.0 represents pure black and 1.0
represents pure white independently of the data type of the input
image.  This is, for a @acronym{JPEG} image the luminance@tie{}255
maps to 1.0 in the normalized interval and for a 32@dmn{bit}
@acronym{TIFF} picture the highest luminance value@tie{}4294967295
also maps to 1.0.  The middle of the luminance interval, 0.5, is where
a neutral gray tone ends up with every camera that had no exposure
correction dialed in, for example the image of a gray- or white-card.

The exposure weighting algorithm only looks at a single pixel at a
time; the pixel's neighborhood is not taken into account.

The weighting function is the Gaussian
@ifinfo
@display
@math{w_exp(Y) = exp(-0.5 * ((Y - Mu) / Sigma)^2),}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <msub>
                <mi>w</mi>
                <mtext>exp</mtext>
            </msub>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mi>Y</mi>
                <mo>)</mo>
            </mrow>
        </mrow>
        <mo>=</mo>
        <mrow>
            <mtext>exp</mtext>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mo>-</mo>
                <mfrac>
                    <mn>1</mn>
                    <mn>2</mn>
                </mfrac>
                <mo>&InvisibleTimes;</mo>
                <msup>
                    <mrow>
                        <mo>(</mo>
                        <mfrac>
                            <mrow>
                                <mi>Y</mi>
                                <mo>-</mo>
                                <mi mathvariant="italic">Mu</mi>
                            </mrow>
                            <mi mathvariant="italic">Sigma</mi>
                        </mfrac>
                        <mo>)</mo>
                    </mrow>
                    <mn>2</mn>
                </msup>
                <mo>)</mo>
            </mrow>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    w_{\mathrm{exp}}(Y) =
    \exp\left(-{1 \over 2}
              \left(Y - \mathit{Mu} \over \mathit{Sigma} \right)^2\right),
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:csymbol>
                    <mml:msub>
                        <mml:mi>w</mml:mi>
                        <mml:mi mathvariant="normal">exp</mml:mi>
                    </mml:msub>
                </mml:csymbol>
                <mml:ci>Y</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:exp/>
                <mml:apply>
                    <mml:times/>
                    <mml:apply>
                        <mml:minus/>
                        <mml:apply>
                            <mml:divide/>
                            <mml:cn>1</mml:cn>
                            <mml:cn>2</mml:cn>
                        </mml:apply>
                    </mml:apply>
                    <mml:apply>
                        <mml:power/>
                        <mml:apply>
                            <mml:divide/>
                            <mml:apply>
                                <mml:minus/>
                                <mml:ci>Y</mml:ci>
                                <mml:ci>Mu</mml:ci>
                            </mml:apply>
                            <mml:ci>Sigma</mml:ci>
                        </mml:apply>
                        <mml:cn>2</mml:cn>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@noindent
whose center@tie{}@math{Mu} and width@tie{}@math{Sigma} are controlled
by the command line options@tie{}@option{--exposure-mu} and @option{--exposure-sigma}
respectively.  @math{Mu} defaults to @value{src::default-exposure-mu}
and @math{Sigma} defaults to @value{src::default-exposure-sigma}.
@ref{Figure:gaussian} shows a Gaussian.

@float Figure,Figure:gaussian
@vimage{gaussian}

@caption{Gaussian function with the parameters @var{Mu} = 0.5 and @var{Sigma} = 0.2.}

@shortcaption{Gaussian function}
@end float

The options@tie{}@option{--exposure-mu} and @option{--exposure-sigma} are for
fine-tuning the final result without changing the set of input images.
Option@tie{}@option{--exposure-mu} sets the point @var{Mu} of optimum
exposure.  Increasing @var{Mu} makes Enfuse prefer lighter pixels,
rendering the final image lighter, and vice versa.
Option@tie{}@option{--exposure-sigma} defines the range @var{Sigma} of
acceptable exposures.  Small values of @var{Sigma} penalize exposures
that deviate from @var{Mu} more, and vice versa.

@optionsummaryheading{}

@table @option
@item --exposure-weight
@ref{Fusion Options}

@item --exposure-mu
@ref{Fusion Options}

@item --exposure-sigma
@ref{Fusion Options}

@item --gray-projector
@ref{Expert Options}
@end table


@node Saturation Weighting
@section Saturation Weighting
@cindex weighting, saturation

Saturation weighting prefers pixels with a high saturation.

Enfuse computes the saturation of a pixel according to the following
algorithm.

@example
@group
@var{max} := maximum(@var{R}, @var{G}, @var{B})
@var{min} := minimum(@var{R}, @var{G}, @var{B})
@b{if} @var{max} = @var{min} @b{then}
    @var{saturation} := 0
@b{else}
    @var{sum} := @var{max} + @var{min}
    @var{difference} := @var{max} - @var{min}
    @b{if} @var{sum} @leq{} 1 @b{then}
        @var{saturation} := @var{difference} / @var{sum}
    @b{else}
        @var{saturation} := @var{difference} / (2 - @var{sum})
    @b{end if}
@b{end if}
@end group
@end example

@noindent
Obviously, saturation weighting can only be defined for @acronym{RGB}
images, not for grayscale ones!  If you need something similar, check
out @ref{Local Entropy Weighting}; entropy weighting works for both
@acronym{RGB} and grayscale pictures.

The saturation weighting algorithm only looks at a single pixel at a
time; the pixel's neighborhood is not taken into account.

@optionsummaryheading{}

@table @option
@item --saturation-weight
@ref{Fusion Options}
@end table


@node Local Contrast Weighting
@section Local Contrast Weighting
@cindex weighting, local contrast

Local contrast weighting favors pixels inside a high contrast
neighborhood.  The notion of ``high contrast'' is defined either by
two different criteria or by a blend of both:

@itemize
@item
The standard deviation (@acronym{SDev}) of all the pixels in the local
analysis window is large.  @xref{Standard Deviation}.

@item
The Laplacian-of-Gaussian (@acronym{LoG}) has a large magnitude.
@xref{Laplacian of Gaussian}.

@item
If the @acronym{LoG} magnitude is below a given threshold, use
@acronym{SDev} data, otherwise stick with @acronym{LoG}.
@xref{Blend SDev and LoG}.
@end itemize

Enfuse converts every @acronym{RGB} image to grayscale before it
determines its contrast.  Option@tie{}@option{--gray-projector}
(@pxref{Expert Options}) controls the projector function.  Depending
on the subject, one of several grayscale projectors may yield the best
black-and-white contrast for image fusion.

In the following sections we describe each algorithm in detail.

@menu
* Standard Deviation::          Standard deviation (@acronym{SDev})
* Laplacian of Gaussian::       @acronym{LoG}, a second derivative method
* Blend SDev and LoG::          Mix and match @acronym{SDev} and @acronym{LoG}
* Scaling and Choice of Mode::  How parameters do not scale; neither does mode
@end menu


@node Standard Deviation
@subsection Standard Deviation
@cindex weighting, contrast using standard deviation
@cindex contrast weighting using standard deviation

@cindex local analysis window
@cindex window, local-analysis
The pixel under consideration@tie{}C sits exactly in the center of a
square, the so-called @dfn{local analysis window}.  It always has an
uneven edge length.  The user sets the size with
option@tie{}@option{--contrast-window-size}.
@ref{Figure:local-analysis-window} shows two windows with different
sizes.

@float Figure,Figure:local-analysis-window
@vimage{local-analysis-window}

@caption{Examples of local analysis windows for the sizes 3 and 5.  ``C'' marks the center where the pixel gets the weight.  ``N'' are neighboring pixels, which all contribute equally to the weight.}

@shortcaption{Local analysis window}
@end float

During the analysis, Enfuse scans the local analysis window across all
rows and all columns@footnote{In the current implementation a
@code{floor(contrast-window-size / 2)} wide border around the images
remains unprocessed and gets a weight of zero.} of each of the input
images to compute the contrast weight of every pixel.

@optionsummaryheading{}

@table @option
@item --contrast-weight
@ref{Fusion Options}

@item --hard-mask
@ref{Fusion Options}

@item --contrast-window-size
@ref{Expert Options}

@item --gray-projector
@ref{Expert Options}
@end table


@subsubsection Statistical Moments
@cindex statistical moments

@cindex probability function
We start with the @dfn{probability function} @math{w} of the random
variable@tie{}@math{X}:
@ifinfo
@display
@math{w: x --> p(@{omega: X(omega) = x@})}.
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mi>w</mi>
        <mo>:</mo>
        <mrow>
            <mi>x</mi>
            <mo>&rightarrow;</mo>
            <mi>p</mi>
            <mo>&ApplyFunction;</mo>
            <mo>(</mo>
            <mrow>
                <mo>&lcub;</mo>
                <mrow>
                    <mi>&omega;</mi>
                    <mo>:</mo>
                    <mrow>
                        <mi>X</mi>
                        <mo>&ApplyFunction;</mo>
                        <mrow>
                            <mo>(</mo>
                            <mi>&omega;</mi>
                            <mo>)</mo>
                        </mrow>
                        <mo>=</mo>
                        <mi>x</mi>
                    </mrow>
                </mrow>
                <mo>&rcub;</mo>
            </mrow>
            <mo>)</mo>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    w: x \rightarrow p(\{\omega: X(\omega) = x\}).
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:apply>
            <mml:csymbol>
                <mml:mo>:</mml:mo>
            </mml:csymbol>
            <mml:ci>w</mml:ci>
            <mml:lambda>
                <mml:bvar>
                    <mml:ci>x</mml:ci>
                </mml:bvar>
                <mml:apply>
                    <mml:ci>p</mml:ci>
                    <mml:set>
                        <mml:bvar>
                            <mml:ci>&omega;</mml:ci>
                        </mml:bvar>
                        <mml:condition>
                            <mml:reln>
                                <mml:eq/>
                                <mml:apply>
                                    <mml:ci>X</mml:ci>
                                    <mml:ci>&omega;</mml:ci>
                                </mml:apply>
                                <mml:ci>x</mml:ci>
                            </mml:reln>
                        </mml:condition>
                    </mml:set>
                </mml:apply>
            </mml:lambda>
        </mml:apply>
    </mml:math>
</informalequation>
@end docbook

@noindent
It associates a probability@tie{}@math{p} with each of the @math{n}
different possible outcomes@tie{}@inlineomega{} of the random
variable@tie{}@math{X}.
@cindex expectation value
Based on @math{w}, we define the @dfn{expectation value} or ``First
Moment'' of the random variable@tie{}@math{X}:
@ifinfo
@display
@math{Ex X := sum(x_i * w(x_i), i = 1..n).}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mo mathvariant="sans-serif">Ex</mo>
            <mo>&ApplyFunction;</mo>
            <mi>X</mi>
        </mrow>
        <mo>:=</mo>
        <mrow>
            <munderover>
                <mo>&sum;</mo>
                <mrow>
                    <mi>i</mi>
                    <mo>=</mo>
                    <mn>1</mn>
                </mrow>
                <mi>n</mi>
            </munderover>
            <msub>
                <mi>x</mi>
                <mi>i</mi>
            </msub>
            <mo>&times;</mo>
            <mi>w</mi>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <msub>
                    <mi>x</mi>
                    <mi>i</mi>
                </msub>
                <mo>)</mo>
            </mrow>
            <mtext>.</mtext>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    \hbox{\sf Ex } X := \sum_{i = 1}^n x_i w(x_i).
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:csymbol>
                    <mml:mtext mathvariant="sans-serif">Ex</mml:mtext>
                </mml:csymbol>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:moment/>
                <mml:degree>
                    <mml:cn>1</mml:cn>
                </mml:degree>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:sum/>
                <mml:bvar>
                    <mml:ci>i</mml:ci>
                </mml:bvar>
                <mml:lowlimit>
                    <mml:cn>1</mml:cn>
                </mml:lowlimit>
                <mml:uplimit>
                    <mml:ci>n</mml:ci>
                </mml:uplimit>
                <mml:apply>
                    <mml:times/>
                    <mml:apply>
                        <mml:selector/>
                        <mml:ci>x</mml:ci>
                        <mml:ci>i</mml:ci>
                    </mml:apply>
                    <mml:apply>
                        <mml:ci>w</mml:ci>
                        <mml:apply>
                            <mml:selector/>
                            <mml:ci>x</mml:ci>
                            <mml:ci>i</mml:ci>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@cindex variance
@noindent
Using the definition of the expectation value, we define the
@dfn{variance}, or ``Second Moment'' as
@ifinfo
@display
@math{Var X := Ex((X - Ex X)^2)},
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mo mathvariant="sans-serif">Var</mo>
        <mo>&ApplyFunction;</mo>
        <mi>X</mi>
    </mrow>
    <mo>:=</mo>
    <mrow>
        <mo mathvariant="sans-serif">Ex</mo>
        <mo>&ApplyFunction;</mo>
        <mrow>
            <mo>(</mo>
            <msup>
                <mrow>
                    <mo>(</mo>
                    <mi>X</mi>
                    <mo>-</mo>
                    <mrow>
                        <mo mathvariant="sans-serif">Ex</mo>
                        <mo>&ApplyFunction;</mo>
                        <mi>X</mi>
                    </mrow>
                    <mo>)</mo>
                </mrow>
                <mn>2</mn>
            </msup>
            <mo>)</mo>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    \hbox{\sf Var } X := \hbox{\sf Ex}\left( (X - \hbox{\sf Ex } X)^2 \right),
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:csymbol>
                    <mml:mtext mathvariant="sans-serif">Var</mml:mtext>
                </mml:csymbol>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:variance/>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:moment/>
                <mml:degree>
                    <mml:cn>2</mml:cn>
                </mml:degree>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:csymbol>
                    <mml:mtext mathvariant="sans-serif">Ex</mml:mtext>
                </mml:csymbol>
                <mml:apply>
                    <mml:power/>
                    <mml:apply>
                        <mml:minus/>
                        <mml:ci>X</mml:ci>
                        <mml:apply>
                            <mml:csymbol>
                                <mml:mtext mathvariant="sans-serif">Ex</mml:mtext>
                            </mml:csymbol>
                            <mml:ci>X</mml:ci>
                        </mml:apply>
                    </mml:apply>
                    <mml:cn>2</mml:cn>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@cindex standard deviation
@noindent
and the @dfn{standard deviation} as
@ifinfo
@display
@math{Sdev X := sqrt(Var X)}.
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mo>&sigma;</mo>
            <mo>&ApplyFunction;</mo>
            <mi>X</mi>
        </mrow>
        <mo>:=</mo>
        <msqrt>
            <mo mathvariant="sans-serif">Var</mo>
            <mo>&ApplyFunction;</mo>
            <mi>X</mi>
        </msqrt>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    \sigma X := \sqrt{\hbox{\sf Var } X}.
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:sdev/>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:root/>
                <mml:degree>
                    <mml:cn>2</mml:cn>
                </mml:degree>
                <mml:apply>
                    <mml:moment/>
                    <mml:degree>
                        <mml:cn>2</mml:cn>
                    </mml:degree>
                    <mml:ci>X</mml:ci>
                </mml:apply>
            </mml:apply>
            <mml:apply>
                <mml:root/>
                <mml:degree>
                    <mml:cn>2</mml:cn>
                </mml:degree>
                <mml:apply>
                    <mml:csymbol>
                        <mml:mtext mathvariant="sans-serif">Var</mml:mtext>
                    </mml:csymbol>
                    <mml:ci>X</mml:ci>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

Obviously, the variance of @math{X} is the expectation value of the
squared deviation from the expectation value of @math{X} itself.  Note
that the variance's dimension is @math{X}'s dimension squared; the
standard deviation rectifies the dimension to make it comparable with
@math{X} itself again.


@subsubsection Estimators
@cindex estimators

In Enfuse, we assume that @math{X} follows a uniform probability
function@tie{}@math{w(x)} = const.  That is, all pixel values in the
local analysis window are considered to be equally probable.  Thus,
the expectation value and the variance can be estimated from the pixel
values like this
@ifinfo
@display
@math{Ex X = sum(x_i, i = 1..n) / n.}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mo mathvariant="sans-serif">Ex</mo>
            <mo>&ApplyFunction;</mo>
            <mi>X</mi>
        </mrow>
        <mo>:=</mo>
        <mrow>
            <mfrac>
                <mn>1</mn>
                <mi>n</mi>
            </mfrac>
            <mo>&InvisibleTimes;</mo>
            <mrow>
                <munderover>
                    <mo>&sum;</mo>
                    <mrow>
                        <mi>i</mi>
                        <mo>=</mo>
                        <mn>1</mn>
                    </mrow>
                    <mi>n</mi>
                </munderover>
                <msub>
                    <mi>x</mi>
                    <mi>i</mi>
                </msub>
            </mrow>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    \hbox{\sf Ex } X := {1 \over n} \sum_{i = 1}^n x_i.
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:csymbol>
                    <mml:mtext mathvariant="sans-serif">Ex</mml:mtext>
                </mml:csymbol>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:times/>
                <mml:apply>
                    <mml:divide/>
                    <mml:cn>1</mml:cn>
                    <mml:ci>n</mml:ci>
                </mml:apply>
                <mml:apply>
                    <mml:sum/>
                    <mml:bvar>
                        <mml:ci>i</mml:ci>
                    </mml:bvar>
                    <mml:lowlimit>
                        <mml:cn>1</mml:cn>
                    </mml:lowlimit>
                    <mml:uplimit>
                        <mml:ci>n</mml:ci>
                    </mml:uplimit>
                    <mml:apply>
                        <mml:selector/>
                        <mml:ci>x</mml:ci>
                        <mml:ci>i</mml:ci>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@noindent
In other words: the expectation value is the arithmetic mean of the
lightness of all pixels in the local analysis window.  Analogously,
the variance becomes
@ifinfo
@display
@math{Var X = sum((x_i - Ex x)^2, i = 1..n) / (n - 1).}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mo mathvariant="sans-serif">Var</mo>
            <mo>&ApplyFunction;</mo>
            <mi>X</mi>
        </mrow>
        <mo>:=</mo>
        <mfrac>
            <mn>1</mn>
            <mrow>
                <mi>n</mi>
                <mo>-</mo>
                <mn>1</mn>
            </mrow>
        </mfrac>
        <mo>&InvisibleTimes;</mo>
        <mrow>
            <mo mathvariant="sans-serif">Ex</mo>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <msup>
                    <mrow>
                        <mo>(</mo>
                        <mi>X</mi>
                        <mo>-</mo>
                        <mrow>
                            <mo mathvariant="sans-serif">Ex</mo>
                            <mo>&ApplyFunction;</mo>
                            <mi>X</mi>
                        </mrow>
                        <mo>)</mo>
                    </mrow>
                    <mn>2</mn>
                </msup>
                <mo>)</mo>
            </mrow>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    \hbox{\sf Var } X :=
    {1 \over {n - 1}} \, \hbox{\sf Ex}\left( (X - \hbox{\sf Ex } X)^2 \right).
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:csymbol>
                    <mml:mtext mathvariant="sans-serif">Var</mml:mtext>
                </mml:csymbol>
                <mml:ci>X</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:times/>
                <mml:apply>
                    <mml:divide/>
                    <mml:cn>1</mml:cn>
                    <mml:apply>
                        <mml:minus/>
                        <mml:ci>n</mml:ci>
                        <mml:cn>1</mml:cn>
                    </mml:apply>
                </mml:apply>
                <mml:apply>
                    <mml:csymbol>
                        <mml:mtext mathvariant="sans-serif">Ex</mml:mtext>
                    </mml:csymbol>
                    <mml:apply>
                        <mml:power/>
                        <mml:apply>
                            <mml:minus/>
                            <mml:ci>X</mml:ci>
                            <mml:apply>
                                <mml:csymbol>
                                    <mml:mtext mathvariant="sans-serif">Ex</mml:mtext>
                                </mml:csymbol>
                                <mml:ci>X</mml:ci>
                            </mml:apply>
                        </mml:apply>
                        <mml:cn>2</mml:cn>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook


@node Laplacian of Gaussian
@subsection Laplacian of Gaussian
@cindex weighting, contrast using laplacian-of--gaussian
@cindex contrast weighting using laplacian-of--gaussian

@cindex Laplacian of Gaussian (@acronym{LoG})
The @dfn{Laplacian of Gaussian} (@acronym{LoG}) is an operator to
detect edges in an image.  Sometimes the @acronym{LoG}-operator is
also called @sc{Marr}-@sc{Hildreth} operator.  A Laplacian-of-Gaussian
operator,
@uref{http://@/hci.iwr.uni-@/heidelberg.de/@/vigra/@/doc/@/vigra/@/group__@/Common@/Convolution@/Filters.html,
@code{vigra::@/laplacian@/Of@/Gaussian}} is part of the
package@tie{}@uref{http://@/hci.iwr.uni-@/heidelberg.de/@/vigra/,
@acronym{VIGRA}} that Enfuse is built upon and is used for edge
detection if option@tie{}@option{--contrast-edge-scale} is non-zero and
@option{--contrast-min-curvature} equal to or less than zero.

Let the Gaussian function be
@ifinfo
@display
@math{g(x, y) = 1/pi * exp((x^2 + y^2) / (2 * sigma^2))/(2 * sigma^2)}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mi>g</mi>
            <mfenced>
                <mi>x</mi>
                <mi>y</mi>
            </mfenced>
        </mrow>
        <mo>=</mo>
        <mrow>
            <mfrac>
                <mn>1</mn>
                <mrow>
                    <mn>2</mn>
                    <mo>&InvisibleTimes;</mo>
                    <mi>&pi;</mi>
                    <mo>&InvisibleTimes;</mo>
                    <msup>
                        <mi>&sigma;</mi>
                        <mn>2</mn>
                    </msup>
                </mrow>
            </mfrac>
            <mo>&InvisibleTimes;</mo>
            <mtext>exp</mtext>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mo>-</mo>
                <mfrac>
                    <mrow>
                        <msup>
                            <mi>x</mi>
                            <mn>2</mn>
                        </msup>
                        <mo>+</mo>
                        <msup>
                            <mi>y</mi>
                            <mn>2</mn>
                        </msup>
                    </mrow>
                    <mrow>
                        <mn>2</mn>
                        <mo>&InvisibleTimes;</mo>
                        <msup>
                            <mi>&sigma;</mi>
                            <mn>2</mn>
                        </msup>
                    </mrow>
                </mfrac>
                <mo>)</mo>
            </mrow>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    g(x, y) =
    {1 \over {2 \pi \sigma^2}} \,
    {\exp\left(-{{x^2 + y^2} \over {2 \sigma^2}}\right)}
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:ci>g</mml:ci>
                <mml:ci>x</mml:ci>
                <mml:ci>y</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:times/>
                <mml:apply>
                    <mml:divide/>
                    <mml:cn>1</mml:cn>
                    <mml:apply>
                        <mml:times/>
                        <mml:cn>2</mml:cn>
                        <mml:csymbol>&pi;</mml:csymbol>
                        <mml:apply>
                            <mml:power/>
                            <mml:ci>&sigma;</mml:ci>
                            <mml:cn>2</mml:cn>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
                <mml:apply>
                    <mml:exp/>
                    <mml:apply>
                        <mml:minus/>
                        <mml:apply>
                            <mml:divide/>
                            <mml:apply>
                                <mml:plus/>
                                <mml:apply>
                                    <mml:power/>
                                    <mml:ci>x</mml:ci>
                                    <mml:cn>2</mml:cn>
                                </mml:apply>
                                <mml:apply>
                                    <mml:power/>
                                    <mml:ci>y</mml:ci>
                                    <mml:cn>2</mml:cn>
                                </mml:apply>
                            </mml:apply>
                            <mml:apply>
                                <mml:times/>
                                <mml:cn>2</mml:cn>
                                <mml:apply>
                                    <mml:power/>
                                    <mml:ci>&sigma;</mml:ci>
                                    <mml:cn>2</mml:cn>
                                </mml:apply>
                            </mml:apply>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@noindent
The parameter@tie{}@inlinesigma{}, the argument of
option@tie{}@option{--contrast-edge-scale}, is the length scale on which edges
are detected by @math{g(x, y)}.  We apply the Laplacian operator in
Cartesian coordinates
@ifinfo
@display
@math{Delta := Nabla o Nabla = (d^2/dx^2 + d^2/dy^2)}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mi>&Delta;</mi>
        </mrow>
        <mo>&equiv;</mo>
        <mrow>
            <mi>&nabla;</mi>
            <mo>&CenterDot;</mo>
            <mi>&nabla;</mi>
        </mrow>
        <mo>=</mo>
        <mrow>
            <mfrac>
                <msup>
                    <mo>&PartialD;</mo>
                    <mn>2</mn>
                </msup>
                <mrow>
                    <mo>&PartialD;</mo>
                    <msup>
                        <mi>x</mi>
                        <mn>2</mn>
                    </msup>
                </mrow>
            </mfrac>
            <mo>+</mo>
            <mfrac>
                <msup>
                    <mo>&PartialD;</mo>
                    <mn>2</mn>
                </msup>
                <mrow>
                    <mo>&PartialD;</mo>
                    <msup>
                        <mi>y</mi>
                        <mn>2</mn>
                    </msup>
                </mrow>
            </mfrac>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    \bigtriangleup \equiv \nabla \cdot \nabla =
    {\partial^2 \over \partial x^2} + {\partial^2 \over \partial y^2}
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:laplacian/>
            </mml:apply>
            <mml:apply>
                <mml:scalarproduct/>
                <mml:apply>
                    <mml:grad/>
                </mml:apply>
                <mml:apply>
                    <mml:grad/>
                </mml:apply>
            </mml:apply>
            <mml:apply>
                <mml:plus/>
                <mml:apply>
                    <mml:partialdiff/>
                    <mml:bvar>
                        <mml:ci>x</mml:ci>
                        <mml:degree>
                            <mml:cn>2</mml:cn>
                        </mml:degree>
                    </mml:bvar>
                </mml:apply>
                <mml:apply>
                    <mml:partialdiff/>
                    <mml:bvar>
                        <mml:ci>y</mml:ci>
                        <mml:degree>
                            <mml:cn>2</mml:cn>
                        </mml:degree>
                    </mml:bvar>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

to @math{g(x, y)}, to arrive at a continuous representation of the
two-dimensional filter kernel
@ifinfo
@display
@math{k(x, y) = (xi^2 - 1) * exp(-xi^2) / (pi * sigma^4),}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <mi>k</mi>
            <mfenced>
                <mi>x</mi>
                <mi>y</mi>
            </mfenced>
        </mrow>
        <mo>=</mo>
        <mrow>
            <mfrac>
                <mrow>
                    <msup>
                        <mi>&xi;</mi>
                        <mn>2</mn>
                    </msup>
                    <mo>-</mo>
                    <mn>1</mn>
                </mrow>
                <mrow>
                    <mi>&pi;</mi>
                    <mo>&InvisibleTimes;</mo>
                    <msup>
                        <mi>&sigma;</mi>
                        <mn>4</mn>
                    </msup>
                </mrow>
            </mfrac>
            <mo>&InvisibleTimes;</mo>
            <mo>exp</mo>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mo>-</mo>
                <msup>
                    <mi>&xi;</mi>
                    <mn>2</mn>
                </msup>
                <mo>)</mo>
            </mrow>
        </mrow>
        <mtext>,</mtext>
    </mrow>
</math>
@end html
@tex
$$
    k(x, y) = {{\xi^2 - 1} \over {\pi \sigma^4}} \exp(-\xi^2),
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:ci>k</mml:ci>
                <mml:ci>x</mml:ci>
                <mml:ci>y</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:times/>
                <mml:apply>
                    <mml:divide/>
                    <mml:apply>
                        <mml:minus/>
                        <mml:apply>
                            <mml:power/>
                            <mml:ci>&xi;</mml:ci>
                            <mml:cn>2</mml:cn>
                        </mml:apply>
                        <mml:cn>1</mml:cn>
                    </mml:apply>
                    <mml:apply>
                        <mml:times/>
                        <mml:csymbol>&pi;</mml:csymbol>
                        <mml:apply>
                            <mml:power/>
                            <mml:ci>&sigma;</mml:ci>
                            <mml:cn>4</mml:cn>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
                <mml:apply>
                    <mml:exp/>
                    <mml:apply>
                        <mml:minus/>
                        <mml:apply>
                            <mml:power/>
                            <mml:ci>&xi;</mml:ci>
                            <mml:cn>2</mml:cn>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

where we have used the dimensionless distance@tie{}@inlinexi{} from
the origin
@ifinfo
@display
@math{xi^2 = (x^2 + y^2) / (2 * sigma^2).}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <msup>
                <mi>&xi;</mi>
                <mn>2</mn>
            </msup>
        </mrow>
        <mo>=</mo>
        <mrow>
            <mfrac>
                <mrow>
                    <msup>
                        <mi>x</mi>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <msup>
                        <mi>y</mi>
                        <mn>2</mn>
                    </msup>
                </mrow>
                <mrow>
                    <mn>2</mn>
                    <mo>&InvisibleTimes;</mo>
                    <msup>
                        <mi>&sigma;</mi>
                        <mn>2</mn>
                    </msup>
                </mrow>
            </mfrac>
        </mrow>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    \xi^2 = {{x^2 + y^2} \over {2 \sigma^2}}.
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:power/>
                <mml:ci>&xi;</mml:ci>
                <mml:cn>2</mml:cn>
            </mml:apply>
            <mml:apply>
                <mml:divide/>
                <mml:apply>
                    <mml:plus/>
                    <mml:apply>
                        <mml:power/>
                        <mml:ci>x</mml:ci>
                        <mml:cn>2</mml:cn>
                    </mml:apply>
                    <mml:apply>
                        <mml:power/>
                        <mml:ci>y</mml:ci>
                        <mml:cn>2</mml:cn>
                    </mml:apply>
                </mml:apply>
                <mml:apply>
                    <mml:times/>
                    <mml:cn>2</mml:cn>
                    <mml:apply>
                        <mml:power/>
                        <mml:ci>&sigma;</mml:ci>
                        <mml:cn>2</mml:cn>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@noindent
Enfuse uses a discrete approximation of @math{k} in the convolution
with the image.  The operator is radially symmetric with respect to
the origin, which is why we can easily plot it in
@ref{Figure:laplacian-of-gaussian}, setting
@ifinfo
@math{R = sqrt(x^2 + y^2)}.
@end ifinfo
@html
<mathinline xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
    <mrowinline>
        <mi>R</mi>
        <mo>=</mo>
        <mrowinline>
            <msqrtinline>
                <msupinline>
                    <mi>x</mi>
                    <mn>2</mn>
                </msupinline>
                <mo>+</mo>
                <msupinline>
                    <mi>y</mi>
                    <mn>2</mn>
                </msupinline>
            </msqrtinline>
        </mrowinline>
        <mtext>.</mtext>
    </mrowinline>
</mathinline>
@end html
@tex
$R = \sqrt{x^2 + y^2}$.
@end tex
@docbook
<inlineequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:ci>R</mml:ci>
            <mml:apply>
                <mml:root/>
                <mml:degree>
                    <mml:cn>2</mml:cn>
                </mml:degree>
                <mml:apply>
                    <mml:plus/>
                    <mml:apply>
                        <mml:power/>
                        <mml:ci>x</mml:ci>
                        <mml:cn>2</mml:cn>
                    </mml:apply>
                    <mml:apply>
                        <mml:power/>
                        <mml:ci>y</mml:ci>
                        <mml:cn>2</mml:cn>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</inlineequation>
@end docbook

@float Figure,Figure:laplacian-of-gaussian
@vimage{laplacian-of-gaussian}

@caption{Laplacian-of-Gaussian function for @inlinesigma{} = 0.5.}

@shortcaption{Laplacian-of-Gaussian}
@end float

@noindent
See also
@uref{http://@/homepages.inf.ed.ac.uk/@/rbf/@/HIPR2/@/log.htm,
@acronym{HIPR2}: Laplacian of Gaussian}.

Sometimes the @acronym{LoG} is plagued by noise in the input images.
After all, it is a numerical approximation of the second derivative
and deriving always ``roughens'' a function.  The (normalized) mask
files relentlessly disclose such problems.  Use
option@tie{}@option{--contrast-min-curvature} with a @emph{negative}
argument@tie{}@var{CURVATURE} to suppress all edges with a curvature
below @minus{}@var{CURVATURE} (which is a positive value).  Check the
effects with the mask files and particularly the hard-mask files
(@file{@value{src::default-hard-mask-template}}) if using
option@tie{}@option{--hard-mask}.

To indicate the @var{CURVATURE} in relative terms, which is
particularly comprehensible for humans, append a percent sign
(@samp{%}).  Try minimum curvatures starting from @minus{}0.5% to
@minus{}3%.

@optionsummaryheading{}

@table @option
@item --contrast-weight
@ref{Fusion Options}

@item --hard-mask
@ref{Fusion Options}

@item --contrast-edge-scale
@ref{Expert Options}

@item --contrast-min-curvature
@ref{Expert Options}
@end table

@node Blend SDev and LoG
@subsection Blend Standard Deviation and Laplacian of Gaussian
@cindex weighting, contrast using a blend of methods
@cindex contrast weighting using a blend of methods

Enfuse can team the standard deviation computation and Laplacian of
Gaussian to deliver the best of both methods.  Use a @emph{positive}
argument@tie{}@var{CURVATURE} with option@tie{}@option{--contrast-min-curvature}
to combine both algorithms.  In this mode of operation Enfuse computes
the @acronym{SDev}-weight and the @acronym{LoG}-weight, then uses the
@acronym{LoG} to decide whether to go with that value or prefer the
@acronym{SDev} data.  If the @acronym{LoG} is greater than
@var{CURVATURE} Enfuse uses the weight delivered by the @acronym{LoG},
otherwise the @acronym{SDev}-weight is rescaled such that its maximum
is equal to @var{CURVATURE}, and the scaled @acronym{SDev} is used as
weight.

This technique merges the two edge detection methods where they are
best.  The @acronym{LoG} excels with clear edges and cannot be fooled
by strong but smooth gradients.  However, it is bad at detecting faint
edges and it is susceptible to noise.  The @acronym{SDev} on the other
hand shines with even the most marginal edges, and resists noise quite
well.  Its weakness is that is is easily deceived by strong and smooth
gradients.  Tuning @var{CURVATURE} the user can pick the best
threshold for a given set of images.

@optionsummaryheading{}

@table @option
@item --contrast-weight
@ref{Fusion Options}

@item --hard-mask
@ref{Fusion Options}

@item --contrast-window-size
@ref{Expert Options}

@item --gray-projector
@ref{Expert Options}

@item --contrast-edge-scale
@ref{Expert Options}

@item --contrast-min-curvature
@ref{Expert Options}
@end table


@node Scaling and Choice of Mode
@subsection Scaling and Choice of Mode
@cindex scaling of parameters
@cindex mode of operation (@acronym{SDev}, @acronym{LoG}, @dots{})

Experience has shown that neither the parameters @var{EDGESCALE} and
@var{CURVATURE} nor the mode of operation (@acronym{SDev}-only,
@acronym{LoG}-only, or a blend of both) scales to different image
sizes.  In practice, this means that if you start with a set of
reduced size images, say 2808@classictimes{}1872 pixels, carefully
optimize @var{EDGESCALE}, @var{CURVATURE} and so on, and find
@acronym{LoG}-only the best mode, and then switch to the original
resolution of 5616@classictimes{}3744 pixels, multiplying (or
dividing) the parameters by four and sticking to @acronym{LoG}-only
might @emph{not} result in the best fused image.  For best quality,
perform the parameter optimization and the search for the most
appropriate mode at the final resolution.


@node Local Entropy Weighting
@section Local Entropy Weighting
@cindex weighting, local entropy

Entropy weighting prefers pixels inside a high entropy neighborhood.

@cindex entropy, definition
Let @math{S} be an @math{n}-ary source.  Watching the output of
@math{S} an observer on average gains the information
@ifinfo
@display
@math{H_a(n) := sum(p(x) * log_a(1 / p(x)), x in S)}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <msub>
                <mi>H</mi>
                <mi>a</mi>
            </msub>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mi>n</mi>
                <mo>)</mo>
            </mrow>
        </mrow>
        <mo>:=</mo>
        <mrow>
            <munder>
                <mo>&Sum;</mo>
                <mrow>
                    <mi>x</mi>
                    <mo>&Element;</mo>
                    <mi>S</mi>
                </mrow>
            </munder>
            <mrow>
                <mi>p</mi>
                <mo>&ApplyFunction;</mo>
                <mrow>
                    <mo>(</mo>
                    <mi>x</mi>
                    <mo>)</mo>
                </mrow>
                <mo>&times;</mo>
                <mrow>
                    <msub>
                        <mtext>log</mtext>
                        <mi>a</mi>
                    </msub>
                    <mo>&ApplyFunction;</mo>
                    <mrow>
                        <mo>(</mo>
                        <mn>1</mn>
                        <mo>/</mo>
                        <mrow>
                            <mi>p</mi>
                            <mo>&ApplyFunction;</mo>
                            <mrow>
                                <mo>(</mo>
                                <mi>x</mi>
                                <mo>)</mo>
                            </mrow>
                        </mrow>
                        <mo>)</mo>
                    </mrow>
                </mrow>
            </mrow>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    H_a(n) := \sum_{x \in S} p(x) \log_a(1 / p(x))
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:apply>
                    <mml:selector/>
                    <mml:ci>H</mml:ci>
                    <mml:ci>a</mml:ci>
                </mml:apply>
                <mml:ci>n</mml:ci>
            </mml:apply>
            <mml:apply>
                <mml:sum/>
                <mml:bvar>
                    <mml:ci>x</mml:ci>
                </mml:bvar>
                <mml:condition>
                    <mml:apply>
                        <mml:in/>
                        <mml:ci>x</mml:ci>
                        <mml:ci>S</mml:ci>
                    </mml:apply>
                </mml:condition>
                <mml:apply>
                    <mml:times/>
                    <mml:apply>
                        <mml:ci>p</mml:ci>
                        <mml:ci>x</mml:ci>
                    </mml:apply>
                    <mml:apply>
                        <mml:log/>
                        <mml:logbase>
                            <mml:ci>a</mml:ci>
                        </mml:logbase>
                        <mml:apply other='display="scriptstyle"'>
                            <mml:divide/>
                            <mml:cn>1</mml:cn>
                            <mml:apply>
                                <mml:ci>p</mml:ci>
                                <mml:ci>x</mml:ci>
                            </mml:apply>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@cindex entropy
@noindent
per emitted message, where we assume the knowledge of the probability
function@tie{}@math{p(S)}.  The expectation value@tie{}@math{H_a(n)}
is called @dfn{entropy} of the source@tie{}@math{S}.  Entropy measures
our uncertainty if we are to guess which message gets chosen by the
source in the future.  The unit of the entropy depends on the choice
of the constant@tie{}@math{a > 1}.  Obviously
@ifinfo
@display
@math{H_b(n) = H_a(n) / log_a(b)}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <msub>
                <mi>H</mi>
                <mi>b</mi>
            </msub>
            <mo>&ApplyFunction;</mo>
            <mrow>
                <mo>(</mo>
                <mi>n</mi>
                <mo>)</mo>
            </mrow>
        </mrow>
        <mo>=</mo>
        <mrow>
            <mrow>
                <msub>
                    <mi>H</mi>
                    <mi>a</mi>
                </msub>
                <mo>&ApplyFunction;</mo>
                <mrow>
                    <mo>(</mo>
                    <mi>n</mi>
                    <mo>)</mo>
                </mrow>
            </mrow>
            <mo>/</mo>
            <mrow>
                <msub>
                    <mtext>log</mtext>
                    <mi>a</mi>
                </msub>
                <mo>&ApplyFunction;</mo>
                <mrow>
                    <mo>(</mo>
                    <mi>b</mi>
                    <mo>)</mo>
                </mrow>
            </mrow>
        </mrow>
    </mrow>
</math>
@end html
@tex
$$
    H_b(n) = H_a(n) / \log_a(b)
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:apply>
                    <mml:selector/>
                    <mml:ci>H</mml:ci>
                    <mml:ci>b</mml:ci>
                </mml:apply>
                <mml:ci>n</mml:ci>
            </mml:apply>
             <mml:apply>
                <mml:divide/>
                <mml:apply>
                    <mml:apply>
                        <mml:selector/>
                        <mml:ci>H</mml:ci>
                        <mml:ci>a</mml:ci>
                    </mml:apply>
                    <mml:ci>n</mml:ci>
                </mml:apply>
                <mml:apply>
                    <mml:log/>
                    <mml:logbase>
                        <mml:ci>a</mml:ci>
                    </mml:logbase>
                    <mml:ci>b</mml:ci>
                </mml:apply>
            </mml:apply>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@noindent
holds for all @math{b > 1}.  We use @math{a = 2} for entropy weighting
and set the entropy of the ``impossible message'' to zero according to
@ifinfo
@display
@math{lim(p * log_a(1 / p), p -> 0) = 0.}
@end display
@end ifinfo
@html
<math xmlns="http://www.w3.org/1998/Math/MathML" display="separate">
    <mrow>
        <mrow>
            <munder>
                <mtext>lim</mtext>
                <mrow>
                    <mi>p</mi>
                    <mo>&rightarrow;</mo>
                    <mn>0</mn>
                </mrow>
            </munder>
            <mrow>
                <mi>p</mi>
                <mo>&times;</mo>
                <mrow>
                    <msub>
                        <mtext>log</mtext>
                        <mi>a</mi>
                    </msub>
                    <mo>&ApplyFunction;</mo>
                    <mrow>
                        <mo>(</mo>
                        <mn>1</mn>
                        <mo>/</mo>
                        <mi>p</mi>
                        <mo>)</mo>
                    </mrow>
                </mrow>
            </mrow>
        </mrow>
        <mo>=</mo>
        <mn>0</mn>
        <mtext>.</mtext>
    </mrow>
</math>
@end html
@tex
$$
    \lim_{p \rightarrow 0} \, p \, \log_a(1 / p) = 0.
$$
@end tex
@docbook
<informalequation>
    <mml:math>
        <mml:reln>
            <mml:eq/>
            <mml:apply>
                <mml:limit/>
                <mml:bvar>
                    <mml:ci>p</mml:ci>
                </mml:bvar>
                <mml:condition>
                    <mml:apply>
                        <mml:tendsto/>
                        <mml:ci>p</mml:ci>
                        <mml:ci>0</mml:ci>
                    </mml:apply>
                </mml:condition>
                <mml:apply>
                    <mml:times/>
                    <mml:ci>p</mml:ci>
                    <mml:apply>
                        <mml:log/>
                        <mml:logbase>
                            <mml:ci>a</mml:ci>
                        </mml:logbase>
                        <mml:apply>
                            <mml:divide/>
                            <mml:cn>1</mml:cn>
                            <mml:ci>p</mml:ci>
                        </mml:apply>
                    </mml:apply>
                </mml:apply>
            </mml:apply>
            <mml:cn>0</mml:cn>
        </mml:reln>
    </mml:math>
</informalequation>
@end docbook

@noindent
@ref{Figure:entropy} shows an entropy function.

@float Figure,Figure:entropy
@vimage{entropy}

@caption{Entropy function@tie{}H for an experiment with exactly two outcomes.}

@shortcaption{Entropy function}
@end float

For more on (information) entropy visit
@uref{http://@/en.wikipedia.org/@/wiki/@/Information_@/entropy,
Wikipedia}.

Enfuse computes a pixel's entropy by considering the pixel itself and
its surrounding pixels quite similar to @ref{Local Contrast
Weighting}.  The size of the window is set by
@option{--entropy-window-size}.  Choosing the right size is difficult,
because there is a serious tradeoff between the locality of the data
and the size of the sample used to compute @math{H}.  A large window
results in a large sample size and therefore in a reliable entropy,
but considering pixels far away from the center degrades @math{H} into
a non-local measure.  For small windows the opposite holds true.

Another difficulty arises from the use of entropy as a weighting
function in dark parts of an image, that is, in areas where the
signal-to-noise ratio is low.  Without any precautions, high noise is
taken to be high entropy, which might not be desired.  Use
option@tie{}@option{--entropy-cutoff} to control the black level when
computing the entropy.

On the other extreme side of lightness, very light parts of an image,
the sensor might already have overflown without the signal reaching
1.0 in the normalized luminance interval.  For these pixels the
entropy is zero and Enfuse can be told of the threshold by properly
setting the second argument of @option{--entropy-cutoff}.

@optionsummaryheading{}

@table @option
@item --entropy-weight
@ref{Fusion Options}

@item --entropy-window-size
@ref{Expert Options}

@item --entropy-cutoff
@ref{Expert Options}
@end table


@node Understanding Masks
@chapter Understanding Masks
@cindex understanding masks
@cindex masks, understanding

@include understanding-masks.texi


@node Tuning Memory Usage
@chapter Tuning Memory Usage
@cindex memory, tuning usage of
@opindex -b
@opindex -m

@include tuning-memory-usage.texi


@node Applications
@chapter Applications of Enfuse
@cindex applications of enfuse

This section describes some of the novel possibilities that Enfuse
offers the photographer.  In contrast to the previous chapters, it
centers around the image effects.

@menu
* What Images::                 What makes images fusable?
* Repetition::                  Just taking the same shot multiple times
* Exposure Series::             Varying the exposure time
* Flash Exposure Series::       Varying the flash output
* Polarization Series::         Changing the polarizer angle
* Focus Stacks::                Stacking images with different in-focus distance
@end menu

@node What Images
@section What Makes Images Fusable?
@cindex images, fusable

Images should align well to be suitable for fusion.  However, there is
no hard mathematical rule what ``well'' means.  The alignment
requirements for 16@dmn{MPixel} images to yield a sharp
4"@classictimes{}6" print at 300@dmn{dpi} (``dpi'' means dots per
inch) or even for web presentation are relatively low, whereas the
alignment of 8@dmn{MPixel} images for a 12"@classictimes{}18" print
ought to be tight.

@pindex hugin
If the input images need to be aligned, Hugin (@pxref{Helpful
Programs}) is the tool of choice.  It produces images exactly in the
format that Enfuse expects.

Sometimes images naturally align extremely well so that no
re-alignment is required.  An image series with preprogrammed exposure
steps taken in rapid succession where the camera is mounted on a heavy
tripod and a humongous ball head, mirror lockup, and a cable release
are used, comes to mind.

When in doubt about what will work, try it, and judge for yourself.

@noindent
Useful ideas for a good alignment:

@itemize
@item
Fix all camera parameters that are not explicitly varied.

@table @emph
@item Aperture
Engage full manual (@key{M}) or aperture-priority (@key{A}) mode.

@item Auto-focus
Disable ``Auto Focus''.  Be aware that the auto-focus function could
be linked to shutter-release button position ``half pressed'' or to
the shutter release in insidious ways.

@item Closed eyepiece
(This applies only to single lens reflex cameras.) Close the eyepiece
when using a cable release to suppress variations in stray light.

@item Exposure time/Shutter speed
Use the shortest possible exposure time or, in other words, use the
fastest shutter speed to avoid blur caused by camera shake or motion
blur.

@item Flash power
Explicitly control the flash power of @emph{all} flashes.  This is
sometimes called ``flash exposure lock''.

@item Sensitivity
Disable ``Auto @acronym{ISO}''.

@item White balance
Disable ``Auto White Balance''.  Instead, use the most suitable fixed
white balance or take the white balance off a white card.  When in
doubt, use the setting ``Daylight'' or equivalent.
@end table

@item
Steady the camera by any means.

@itemize
@item
Apply your best camera bracing technique combined with controlled
breathing.

@item
Prefer a monopod, or better, a rigid tripod with a heavy head.

@item
Use a cable release if possible.

@item
(This applies to cameras with a moving mirror only.)  Engage ``mirror
lockup''.

@item
Consider automatic bracketing when applicable.

@item
Activate camera- or lens-based image stabilization if you are sure
that it improves the image quality in your particular case; otherwise
disengage the feature.

For some lens-based image stabilization systems, it is known that they
``lock'' into different positions every time they are activated.
Moreover, some stabilization systems decrease the image quality when
the lens is mounted on a tripod.
@end itemize

@item
Fire in rapid succession.
@end itemize

@c http://www.usa.canon.com/dlc/controller?act=GetArticleAct&articleID=1786


@node Repetition
@section Repetition -- Noise Reduction
@cindex simple series
@cindex series, simple
@cindex noise reduction

@mainpurpose Reduce noise

@noindent
With the default settings, Enfuse computes a weighted average of the
input pixels.  For a series of images, repeated with identical
settings, this results in a reduction of (photon shot) noise.  In
other words, the dynamic range increases slightly, because the higher
signal-to-noise ratio makes darker shades usable.  Furthermore, smooth
or glossy surfaces get a ``cleaner'' look, and edges become visually
sharper.  The nitty-gritty reportage look that sometimes stems from a
high sensitivity setting disappears.

Averaged images, and therefore low-noise images, are the base for a
multitude of techniques like, for example, differences.  The most
prominent method in this class is dark-frame subtraction.

The defaults set
@samp{--exposure-weight=@value{src::default-weight-exposure}} and
@samp{--saturation-weight=@value{src::default-weight-saturation}}.
Eliminating the saturation component with @samp{--saturation-weight=0.0} can
be worth an extra run.


@node Exposure Series
@section Exposure Series -- Dynamic Range Increase
@cindex exposure series
@cindex series, exposure
@cindex dynamic range increase

@mainpurpose Increase manageable dynamic range

@noindent
An exposure series is a set of images taken with identical parameters
except for the exposure time.  Some cameras even provide special
functions to automate recording exposure series.  See the instruction
manual of your model for details.

Enfuse's defaults,
@samp{--exposure-weight=@value{src::default-weight-exposure}} and
@samp{--saturation-weight=@value{src::default-weight-saturation}} are
well suited for fusion of @emph{color} images.  Remember that
saturation weighting only works for @acronym{RGB} data.
Option@tie{}@option{--saturation-weight} helps to control burnt-out
highlights, as these are heavily desaturated.  Alternatively, use
option@tie{}@option{--exposure-cutoff} to suppress noise or blown-out
highlights without altering the overall brightness too much.  If no
image suffers from troublesome highlights, the relative saturation
weight can be reduced and even be set to zero.

For black and white images @option{--entropy-weight} can be an
alternative to @option{--saturation-weight} because it suppresses
overexposed pixels, as these contain little information.  However,
entropy weighting is not limited to gray-scale data; it has been
successfully applied to @acronym{RGB} images, too.  Note that entropy
weighting considers @emph{each} color channel of an @acronym{RGB}
image separately and chooses the channel with the minimum entropy as
representative for the whole pixel.

Enfuse offers the photographer tremendous flexibility in fusing
differently exposed images.  Whether you combine only two pictures or
a series of 21, Enfuse imposes no limits on you.  Accordingly, the
photographic effects achieved range from subtle to surreal, like the
late 1980s ``Max Headroom'' @acronym{TV}-Series, to really unreal.
Like some time ago in the chemical days of photography, when a new
developer opened unseen possibilities for artists, exposure fusion
extends a photographer's expressive space in the digital age.  Whether
the results look good or bad, whether the images are dull or exciting,
is entirely up the artist.

In the next sections we give assistance to starters, and rectify
several misconceptions about Enfuse.

@menu
* Exposure Series Tips::            Some hints for beginners
* Exposure Series Misconceptions::  What works despite the hype
@end menu


@node Exposure Series Tips
@subsection Tips For Beginners
@cindex exposure series, tips for beginners

Here are some tips to get you in business quickly.

@table @emph
@item Include the best single exposure.
Include the exposure you would have taken if you did not use Enfuse in
your series.  It gives you a solid starting point.  Think of the other
images as augmenting this best single exposure to bring out the light
and dark features you would like to see.

@item Begin with as small a number of images as possible.
Pre-visualizing the results of Enfuse is difficult.  The more images
put into the fusion process and the wider their @acronym{EV}-spacing
is, the more challenging visualizing the output image becomes.
Therefore, start off with as few images as possible.

You can take a larger series of images and only use part of it.

@item Start with a moderate @acronym{EV}-spacing.
As has been pointed out in the previous item, a wide
@acronym{EV}-spacing makes pre-visualization harder.  So start out
with a spacing of 2/3@dmn{EV} to 1+1/3@dmn{EV}.
@end table


@node Exposure Series Misconceptions
@subsection Common Misconceptions
@cindex exposure series, common misconceptions

Here are some surprisingly common misconceptions about exposure
series.

@table @emph
@item A single image cannot be the source of an exposure series.
@cindex digital blending
@cindex blending exposures
Raw-files in particular lend themselves to be converted multiple times
and the results being fused together.  The technique is simpler,
faster, and usually even looks better than
@uref{http://@/luminous-@/landscape.com/@/tutorials/@/digital-@/blending.shtml,
digital blending} (as opposed to using a graduated neutral density
filter) or
@uref{http://@/www.gimpguru.org/@/Tutorials/@/Blending@/Exposures/,
blending exposures} in an image manipulation program.  Moreover,
perfect alignment comes free of charge!

@item An exposure series must feature symmetrically-spaced exposures.
Twice wrong!  Neither do the exposures have to be ``symmetric'' like
@{0@dmn{EV}, @minus{}2/3@dmn{EV}, +2/3@dmn{EV}@}, nor does the number
of exposures have to be odd.  Series like
@{@minus{}1@minus{}1/3@dmn{EV}, @minus{}1/3@dmn{EV}, +1/3@dmn{EV}@} or
@{@minus{}1@dmn{EV}, 1@dmn{EV}@} might be just right.  By the way, the
order in which the images were taken does not matter either.

@item An exposure series must cover the whole dynamic range of the scene.
@cindex light probe
If you do not want to cover the whole range, you do not have to.  Some
@acronym{HDR} programs require the user to take a light
probe,@footnote{@uref{http://@/www.debevec.org/, Paul E.@tie{}Debevec}
defines: ``A @dfn{light probe} image is an omnidirectional, high
dynamic range image that records the incident illumination conditions
at a particular point in space.''} whereas Enfuse offers the user
complete freedom of exposure.

@item All exposure values must be different.
You can repeat any exposure as often as you like.  That way you
combine an exposure series with parts of @ref{Repetition}, emphasizing
the multiply occuring exposures and reducing noise.
@end table


@node Flash Exposure Series
@section Flash Exposure Series -- Directed Lighting
@cindex flash exposure series
@cindex series, flash exposure
@cindex dynamic range increase

@mainpurpose ???

...


@node Polarization Series
@section Polarization Series -- Saturation Enhancement
@cindex polarization series
@cindex series, polarization
@cindex saturation enhancement

@mainpurpose Reflection suppression, saturation enhancement

In the current implementation of Enfuse, it is not possible in general
to fuse a polarization series.  Naively abusing
@option{--saturation-weight} will not work.


@node Focus Stacks
@section Focus Stacks -- Depth-of-Field Increase
@cindex focus stacks
@cindex depth-of-focus increase

@mainpurpose Synthetic Depth-of-Field Increase

A @dfn{focus stack} is a series of images where the distance of the
focal plane from the sensor varies.  Sloppily speaking, the images
were focussed at different distances.  Fusing such a stack increases
the depth-of-field (@acronym{DOF}) beyond the physical limits of
diffraction.

@menu
* Why Focus Stacks::            Why take the hassle?
* Preparing Focus Stacks::      How to get suitable input images
* Local Contrast Based Fusing:: Fundamental command line options
* Basic Focus Stacking::        Simple, standard deviation method
* Advanced Focus Stacking::     Advanced, Laplacian technique
* Expert Stacking::             Tips for focus stacking experts
@end menu


@node Why Focus Stacks
@subsection Why create focus stacks?
@cindex focus stacks, why create them

Given

@itemize
@item
a fixed sensor or film size,
@item
a lens' particular focal length, and
@item
@cindex circle-of-confusion
a notion about ``sharpness'', technically speaking the size of the
circle-of-confusion (@acronym{CoC})
@end itemize

@cindex depth-of-field
@noindent
the photographer controls the depth-of-field with the aperture.
Smaller apertures -- this is larger aperture numbers -- increase the
@acronym{DOF} and vice versa.  However, smaller apertures increase
diffraction which in turn renders the image unsharp.  So, there is an
optimum aperture where the photographer gets maximum @acronym{DOF}.
Sadly, for some purposes like macro shots it is not enough.  One way
out is to combine the sharp parts of images focused at different
distances, thereby artificially increasing the total @acronym{DOF}.
This is exactly what Enfuse can do.

@cindex sweet spot aperture
@cindex aperture, sweet spot
All lenses have a so called ``sweet spot'' aperture, where their
resolution is best.  Taking pictures at this aperture, the
photographer squeezes the maximum quality out of the lens.  But: the
``sweet spot'' aperture often is only one or two stops away from wide
open.  Wouldn't it be great to be able combine these best-possible
images to form one high-quality, sufficient-@acronym{DOF} image?
Welcome to Enfuse's local-contrast selection abilities.


@node Preparing Focus Stacks
@subsection Preparing Focus Stacks
@cindex focus stacks, preparation

We are going to combine images with limited @acronym{DOF} to increase
their in-focus parts.  The whole process is about image sharpness.
Therefore, the input images must align very well, not just well, but
very well.  For optimum results the maximum control point distance in
Hugin (@pxref{Helpful Programs}) should not exceed
0.3--0.5@dmn{pixels} to ensure perfect blending.

As in all image fusion operations it is preferable to use 16@dmn{bit}
linear (gamma = 1) images throughout, but 8@dmn{bit} gamma encoded
images will do.  Naturally, high @acronym{SNR} input data always is
welcome.


@node Local Contrast Based Fusing
@subsection Local Contrast Based Fusing
@cindex local-contrast-based fusing
@cindex fusing, local-contrast-based
@cindex focus stacks, fusing

A bare bones call to Enfuse for focus stacking could look like this.

@example
enfuse \
    --exposure-weight=0 \
    --saturation-weight=0 \
    --contrast-weight=1 \
    --hard-mask \
    @dots{} \
    --output=output.tif \
    input-<0000-9999>.tif
@end example

@noindent
Here is what each option causes:

@table @option
@item --exposure-weight=0
Switch @strong{off} exposure based pixel selection.  The default
weight is @value{src::default-weight-exposure}.

@item --saturation-weight=0
Switch @strong{off} saturation based pixel selection.  The default
weight is @value{src::default-weight-saturation}.

@item --contrast-weight=1
Switch @strong{on} pixel selection based on local contrast.

@item --hard-mask
Select the best pixel from the image stack and ignore all others.
Without this option, Enfuse uses all pixels in the stack and weights
them according to their respective quality, which in our case is local
contrast.  Without @option{--hard-mask}, the result will always look a
bit soft.  @xref{Local Contrast Weighting}.
@end table

@noindent
If you want to see some entertaining progress messages --
local-contrast weighting takes a while --, also pass the
@option{--verbose}@tie{}option for a verbose progress report.


@node Basic Focus Stacking
@subsection Basic Focus Stacking
@cindex basic focus stacking
@cindex focus stacking, basic

For a large class of image stacks Enfuse's default algorithm, as
selected in @ref{Local Contrast Based Fusing}, to determine the
sharpness produces nice results.  The algorithm uses a moving square
window, the so-called contrast window.  It computes the standard
deviation of the pixels inside of the window.  The program then
selects the window's center pixel of the image in the stack where the
standard deviation is largest, that is, the local contrast reaches the
maximum.

However, the algorithm fails to deliver good masks for images which
exhibit high contrast edges on the scale of the contrast window size.
The typical artifacts that show up are

@itemize
@item
faint dark seams on the light side of the high contrast edges and

@item
extremely soft, slightly lighter seams on the dark side of the high
contrast edges,
@end itemize

@noindent
where the distance of the seams from the middle of the edge is
comparable to the contrast window size.

If your results do not show any of these artifacts, stick with the
basic algorithm.  Advanced focus stacking, as described in the next
sections, delivers superior results in case of artifacts, though
requires manually tuning several parameters.


@node Advanced Focus Stacking
@subsection Advanced Focus Stacking
@cindex advanced focus stacking
@cindex focus stacking, advanced

If your fused image shows any of the defects described in the previous
section, you can try a more difficult-to-use algorithm that
effectively works around the seam artifacts.  It is described in the
next section.

@menu
* Local Contrast Problem::        What is the problem Kenneth?
* Laplacian Edge Detection::      Using a Laplacian-of-Gaussian to detect edges
* Local Contrast Enhancement::    Boosting local contrast before weighting
* Suppressing Noise or Recognizing Faint Edges::  The best of both worlds
* Focus Stacking Decision Tree::  What to do and how to fuse
@end menu


@node Local Contrast Problem
@subsubsection A Detailed Look at the Problem
@cindex local contrast problem
@cindex problem, local contrast

Let us use an example to illustrate the problem of relating the
sharpness with the local contrast variations.  Say we use a
5@classictimes{}5 contrast window.  Moreover, let @code{sharp_edge}
and @code{smooth_edge} be two specific configurations:

@example
sharp_edge =  [    0,    0,  200,    0,    0;
                   0,  225,    0,    0,    0;
                   0,  255,    0,    0,    0;
                 215,    0,    0,    0,    0;
                 200,    0,    0,    0,    0]
@end example

@example
smooth_edge = [    0,   62,  125,  187,  250;
                   1,   63,  126,  188,  251;
                   2,   65,  127,  190,  252;
                   3,   66,  128,  191,  253;
                   5,   67,  130,  192,  255]
@end example

where @samp{;} separates the rows and @samp{,} separates the columns.
This is in fact @uref{http://@/www.gnu.org/@/software/@/octave/,
Octave} syntax.

@ref{Figure:sharp-edge} and @ref{Figure:smooth-edge} show plots of the
matrices @code{sharp_edge} and @code{smooth_edge}.

@float Figure,Figure:sharp-edge
@vimage{sharp-edge}

@caption{3D plot augmented by contour plot of the matrix@tie{}@code{sharp_edge}.}

@shortcaption{Sharp edge}
@end float

@float Figure,Figure:smooth-edge
@vimage{smooth-edge}

@caption{3D plot augmented by contour plot of the matrix@tie{}@code{smooth_edge}.}

@shortcaption{Smooth edge}
@end float

@noindent
Our intuition lets us ``see'' an extremely sharp edge in the first
matrix, whereas the second one describes an extraordinarily smooth
diagonal intensity ramp.  Which one will be selected?  Well,
@code{sharp_edge} has a standard deviation of 88.07 and
@code{smooth_edge} has 88.41.  Thus, @code{smooth_edge} wins,
contradicting our intuition, and even worse, our intention!

Sadly, configurations like @code{smooth_edge} occur more often with
high-quality, good
@uref{http://@/www.luminous-@/landscape.com/@/essays/@/bokeh.shtml,
bokeh} lenses.  In fact, they are the very manifestation of ``good
bokeh''.  Therefore, Laplacian edge detection plays an important role
when working with high-quality lenses.


@node Laplacian Edge Detection
@subsubsection Laplacian Edge Detection
@cindex laplacian edge detection
@cindex edge detection, laplacian

Enfuse provides a Laplacian-based algorithm that can help in
situations where weighting based on the standard deviation fails.  It
is activated with a positive value for @var{SCALE} in
@code{--contrast-edge-scale}=@/@var{SCALE}.  The Laplacian will detect
two-dimensional @emph{curvature} on the scale of @var{SCALE}.  Here
and in the following we simply speak of ``curvature'' where we mean
``magnitude of curvature''.  That is, we shall not distinguish between
convex and concave edges.  Enfuse always use the magnitude of
curvature for weighting.

Typically, @var{SCALE} ranges between 0.1@dmn{pixels} and
0.5@dmn{pixels}, where 0.3@dmn{pixels} is a good starting point.  To
find the best value for @var{SCALE} though, usually some
experimentation will be necessary.  Use @option{--save-masks} to get
all soft-mask (default:
@file{@value{src::default-soft-mask-template}}) and hard-mask files
(default: @file{@value{src::default-hard-mask-template}}).  Check how
different scales affect the artifacts.  Also @pxref{Understanding
Masks}.


@node Local Contrast Enhancement
@subsubsection Local Contrast Enhancement
@cindex local contrast enhancement
@cindex contrast enhancement, local

Sometimes Enfuse misses smoother edges with
@option{--contrast-edge-scale} and a little local contrast enhancement
(@acronym{LCE}) helps.  Set
@code{--contrast-edge-scale}=@/@var{SCALE}:@/@var{LCE-SCALE}:@/@var{LCE-FACTOR}.
where @var{LCE-SCALE} and @var{LCE-FACTOR} work like the
@uref{http://@/www.cambridgeincolour.com/@/tutorials/@/unsharp-@/mask.htm,
unsharp mask} filters in various image manipulation programs.  Start
with @var{LCE-SCALE} ten times the value of @var{SCALE} and a
@var{LCE-FACTOR} of 2--5.

@var{LCE-SCALE} can be specified as a percentage of @var{SCALE}.
@var{LCE-FACTOR} also can be specified as a percentage.  Examples:

@example
--contrast-edge-scale=0.3:3.0:3
--contrast-edge-scale=0.3:1000%:3.0
--contrast-edge-scale=0.3:3:300%
--contrast-edge-scale=0.3:1000%:300%
@end example

@noindent
By default @acronym{LCE} is turned off.


@node Suppressing Noise or Recognizing Faint Edges
@subsubsection Suppressing Noise or Recognizing Faint Edges
@cindex advanced focus stacking, suppressing noise
@cindex advanced focus stacking, recognizing faint edges

The Laplacian-based algorithm is much better at resisting the seam
problem than the local-contrast algorithm, but it has two
shortcomings:

@enumerate
@item
The Laplacian is very susceptible to noise and
@item
it fails to recognize faint edges.
@end enumerate

@noindent
The @option{--contrast-min-curvature} option helps to mitigate both
flaws.

The argument to @code{--contrast-min-curvature}=@var{CURVATURE} either
is an absolute lightness value, for example 0..255 for 8@dmn{bit} data
and 0..65535 for 16@dmn{bit} data, or, when given with a @samp{%}-sign
it is a relative lightness value ranging from 0% to 100%.

To suppress unreal edges or counter excessive noise, use the
@option{--contrast-min-curvature} option with a @emph{negative}
curvature measure @var{CURVATURE}.  This forces all curvatures less
than @minus{}@var{CURVATURE} to zero.

A @emph{positive} curvature measure @var{CURVATURE} makes Enfuse merge
the @acronym{LoG} data with the local-contrast data.  Every curvature
larger than or equal to @var{CURVATURE} is left unchanged, and every
curvature less than @var{CURVATURE} gets replaced with the rescaled
local-contrast data, such that the largest local contrast is just
below @var{CURVATURE}.  This combines the best parts of both
techniques and ensures a precise edge detection over the whole range
of edge curvatures.

@noindent
@strong{Summary}

@table @code
@item -@/-contrast-edge-scale=0.3
Use @acronym{LoG} to detect edges on a scale of 0.3@dmn{pixels}.
Apply the default grayscale projector: @code{average}.

@item -@/-contrast-edge-scale=0.3 -@/-gray-projector=l-star
Use @acronym{LoG} to detect edges on a scale of 0.3@dmn{pixels}.
Apply the L*-grayscale projector.

@item -@/-contrast-edge-scale=0.3:3:300%
Use @acronym{LoG} to detect edges on a scale of 0.3@dmn{pixels},
pre-sharpen the input images by 300% on a scale of 3@dmn{pixels}.
Apply the default grayscale projector: @code{average}.

@item -@/-contrast-edge-scale=0.3 -@/-contrast-min-curvature=@minus{}0.5%
Use @acronym{LoG} to detect edges on a scale of 0.3@dmn{pixels}.
Apply the default grayscale projector: @code{average} and throw away
all edges with a curvature of less than 0.5%.

@item -@/-contrast-edge-scale=0.3 -@/-contrast-min-curvature=0.5% -@/-contrast-window-size=7
Use @acronym{LoG} to detect edges on a scale of 0.3@dmn{pixels}.
Apply the default grayscale projector: @code{average} and throw away
all edges with a curvature of less than 0.5% and replace the
@acronym{LoG} data between 0% and 0.5% with @acronym{SDev} data.  Use
a window of 7@classictimes{}7@dmn{pixel} window to compute the
@acronym{SDev}.
@end table


@page
@node Focus Stacking Decision Tree
@subsubsection Focus Stacking Decision Tree
@cindex focus stacking decision tree
@cindex decision tree, focus stacking

@ref{Figure:focus-stacking-decision-tree} helps the user to arrive at
a well-fused focus stack with as few steps as possible.

@float Figure,Figure:focus-stacking-decision-tree
@vimage{focus-stack-decision-tree}

@caption{Focus stacking decision tree.}

@shortcaption{Focus stacking decision tree}
@end float

Always start with the default, contrast weighting with a local
contrast window.  Only if seams appear as described in @ref{Advanced
Focus Stacking} switch to Laplacian-of-Gaussian contrast detection.

If some seams remain even in @acronym{LoG}-mode, decrease the
sensitivity of the edge detection with a positive
@option{--contrast-min-curvature}.  A too high value of
@option{--contrast-min-curvature} suppresses fine detail though.  Part
of the detail can be brought back with pre-sharpening, that is,
@ref{Local Contrast Enhancement} or combining @acronym{LoG} with
local-contrast-window mode by using a negative
@option{--contrast-min-curvature}.

Carefully examining the masks (option@tie{}@option{--save-masks}) that
Enfuse uses helps to judge the effects of the parameters.


@node Expert Stacking
@subsection Tips For Focus Stacking Experts
@cindex expert focus stacking tips
@cindex tips, focus stacking experts

We have collected some advice with which even focus-stacking adepts
can benefit.

@itemize
@item
@cindex sensor, use of clean
Ensure that the sensor is clean.

Aligning focus stacks requires varying the viewing angle, which
corresponds to a changing focal length.  Hence, the same pixel on the
sensor gets mapped onto different positions in the final image.  Dirt
spots will occur not only once but as many times as there are images
in the stack -- something that is no fun to correct in postprocessing.

@cindex dark frame
@cindex subtraction of dark frame
@cindex hot pixels
@cindex pixels, hot
Along the same lines, the photographer may want to consider to prepare
dark frames before, and possibly also after, the shoot of the focus
stack, to subtract hot pixels before fusion.

@item
@opindex --hard-mask
Prefer a low-sensitivity setting (``@acronym{ISO}'') on the camera to
get low-noise images.

Fusing with @option{--hard-mask} does not average, and thus does not
suppress any noise in the input images.

@item
If the transition of in-focus to out-of-focus areas is too abrupt,
record the images with closest and farthest focusing distances twice:
first with the intended working aperture, and a second time with a
small aperture (large aperture number).

@cindex natural sharp-unsharp transition
@cindex transition, natural sharp-unsharp
The small aperture will give the fused image a more natural in-focus
to out-of-focus transition and the working-aperture shots supply the
detail in the in-focus regions.
@end itemize


@node Helpful Programs
@chapter Helpful Additional Programs
@cindex helpful programs
@cindex programs, helpful additional

@include helpful-programs.texi


@node Bug Reports
@appendix Bug Reports
@cindex bug reports

@include bug-reports.texi


@node Authors
@appendix Authors
@cindex authors, list of

@include authors.texi


@node FDL
@appendix @acronym{GNU} Free Documentation License
@cindex free documentation license (@acronym{FDL})
@cindex @acronym{GNU} free documentation license

@include fdl.texi


@c
@c End of Document
@c

@c The List-of-Tables and List-of-Figures go right before the indices
@c in all formats but TeX.  For the TeX output they appear right after
@c the Table-of-Contents.
@ifnotdocbook
@ifnottex
@node List of Tables
@unnumbered List of Tables
@listoffloats Table


@node List of Figures
@unnumbered List of Figures
@listoffloats Figure
@end ifnottex


@node Program Index
@unnumbered Program Index
@cindex program index
@cindex index, program

@printindex pg


@node Syntactic-Comment Index
@unnumbered Syntactic-Comment Index
@cindex syntactic-comment index
@cindex index, syntactic-comment

@printindex sc


@node Option Index
@unnumbered Option Index
@cindex option index
@cindex index, option

@printindex op


@node General Index
@unnumbered General Index
@cindex general index
@cindex index, general

@printindex cp
@end ifnotdocbook

@bye
