-
Notifications
You must be signed in to change notification settings - Fork 1
How imfuse works
imfuse generates an overall sharp image from a stack of source images, where each source images is only partially sharp in focus.
- This page describes the general workflow of imfuse.
- The magic is all about generating masks that describe the desired areas of each single image that should contribute to the overall sharp result.
- Make sure the source images are aligned and maybe cropped first.
- Check out the examples.
For best results the stackshot source images need to be aligned.
- You can use tool
stackalign
to create a new folder with aligned source images. - imfuse has an option
--align
. However, I recommend to rather usestackalign
so you can use the aligned images later again. - This needs tool PetteriAimonen/focus-stack.
- Another aligning tool is
align_image_stack
from panorama / hugin tools.
It can take a lot of time to find the best option set. To speed this up, I recommend to work with a cropped part of the source images first.
- First run with option
--background=enfuse
to estimate which parts of the image might be difficult. - Use tool
stackprepare
with option--crop
or--shave
to get a chosen part of the aligned source images. - Run imfuse with the cropped images and several option sets until you find one that suits well. Than run with same option set on the full-sized aligned source images.
I almost always run imfuse with options -CVWXL
.
- Option
-C
,--cache
stores the generated mask files in cache folder~/.cache/imfuse
.- In case you change options to optimize the results, imfuse will re-use the cache files whenever possible. This makes it faster.
- imfuse applies the options in several steps.
- If you change an option of one step, the affected step and all following steps will have to run.
- Changing an option in a late step (like the
--final*
options) is cheap and fast. - Changing
--background
in step 1 is cheap, too, because it does not affect mask generation.
- imfuse applies the options in several steps.
- The default file format to store in cache is
mpc
, that is optimized for fast writing and reading by ImageMagick. However, it needs a lot of disk space. In case you run out of disk space, use slower but smaller compressedtif
with option--maskformat=tif
. - For best performance the cache should be on an SSD hard drive.
-
imfuse --rmcache
cleans the imfuse cache. It can grow really big. The current cache size is shown after each run of imfuse.
- In case you change options to optimize the results, imfuse will re-use the cache files whenever possible. This makes it faster.
- Option
-V
will show you intermediate results in image viewergeeqie
. However, this will slow down imfuse. - Option
-W
will show the result image in image viewerfeh
. - Option
-X
additionally stores the final mask and a depth map. They are shown infeh
, too, and help to analyze the result. - The file name of imfuse by default consists of two numbers, the first one a shorted md5sum of the source images, the second one a shortened md5sum from the given options. This gives a unique file name and sorts images of same source together.
- The options are stored as exif meta data in the image and can be seen with
exiftool -ImageDescription IMAGENAME
. - With option
-L
,--longname
the options are added to the file name.
- The options are stored as exif meta data in the image and can be seen with
You can create a background image on which the result image will be painted on.
- Some backgrounds of interest:
enfuse
,wave
,overlay
. - Example:
--bg=enfuse
. - You can as well use the background option only without all other steps.
- The background will be visible in the result only if the result is partially (semi-)transparent.
- This can happen e.g. with options
--cutalpha
,finalalpha
,--finalthreshold
.
- This can happen e.g. with options
imfuse provides a lot of options to generate masks from the source images.
- The order of the mask generating options does not matter.
- Most mask generating options detect contrast edges in the source images. The idea is that only areas in focus will show sharp edges.
- Most used by myself:
--statistic
,--blur
with two sigma arguments,--morphology
,--wavelet
. - Some mask generators accept arguments for radius, sigma or percent.
- Think of radius and sigma as of brush sizes.
- Low values for radius or sigma show more detail and cause noise.
- High values for radius or sigma show more contrast, less noise and less detail.
- Examples:
--statistic=r4
,--blur=s0.75,S1.2
- Most used by myself:
- Some mask generating options provide color space channels or image comparisons.
- Often useful example:
--darkness=w10
- Often useful example:
The masks generated in step 2 are merged together into one mask.
- The masks contribute to the merged mask according to their weight given mit argument
w
.- If argument
w
is not given, the weights will be calculated automatically to give each mask the same weight.
- If argument
- The merged mask can be adjusted with the
--mask*
options.- The
--mask*
options in general serve to connect the detected contrast edges to also get unsharp areas in between that are likely in focus, too. I call those areasgaps
. - The order of the
--mask*
option matters. Each one will process the result of the previous one. - The
--mask*
options have default values that might be entirely useless depending on the overall setup. Try different values for the arguments. - Option
--masklevel
is enabled by default and always executed at last to stretch the masks to a 0..100% spectrum again. This helps in step 4 to have full range percent values. - Examples:
- Reduce noise and close gaps with
--maskwave=p100
. - Close gaps with
--maskmorph=close,r2,R2
. - Enhance contrast and close gaps with
--maskblur
. However, this can strengthen noise, too. Maybe rather use--cutblur
later.
- Reduce noise and close gaps with
- The
Each source image will be compared with its according mask to decide which parts of it will contribute to the overall sharp result image.
- There might be foreground objects that are superseded by strong background objects.
- Use option
--cutless
to preserve foreground objects.-
--cutless
takes a percent value that you will need to adjust in most cases. - If the foreground objects are not complete, use a lower percent value for
--cutless
. - If undesired unsharp areas appear due to
--cutless
, use a higher percent value for--cutless
.
-
- Use option
- The masks might have major gaps where no sharp edge was found. Also it might look rough.
- Use option
--cutwave
to soften the cut. This also closes some gaps. The percent argument adjusts the overall softness. -
--cutblur
softens the cut in another way than--cutwave
and can also close some gaps.
- Use option
- Further
--cut*
options are available. The order matters. Always use--cutless
first if it is needed.- A quite useful one is
--cutalpha
that makes the cuts semitransparent according to the mask.- Use
--cutbg
before--cutalpha
to fill the background.
- Use
- Scissors: Options
--cutmorph=dilate
,--cutthreshold
and--cutmax
can serve as scissors to cut of borders or parts of the cut mask. However, none of them works really great.
- A quite useful one is
This step mostly serves to change the background to a nice bokeh.
- The
--final*
options base on a final mask that is generated as a maximum of all single masks. - Some
--final*
options create transparency.- The result image might be already partially transparent.
- You can turn off transparency with
--finalalpha=off
. - Transparent results can be painted on a background of step 1.
- You can make the result transparent according to the final mask.
-
--finalalpha
will make weak areas very transparent, but strong areas less transparent.-
--cutalpha
might give better results than--finalalpha
.
-
-
- You can cut off weak areas with
--finalthreshold
. The cut off areas will be transparent.- Adjust the percent argument until all and only weak areas are cut off.
- Add a sigma argument for a soft cut border.
- The result of
--finalthreshold
can be painted on a background image of step 1.
- The result of
- You can blur the background with
--finalblur
.- Use a percent value to tell how much of weak area should be blurred.
- Find out a useful percent value with
--finalthreshold
and drop--finalthreshold
afterwards.--finalthreshold
helps here to see which areas will be blurred.
- Find out a useful percent value with
- Set a sigma argument for strength of blur.
- Different and less invasive is
--finalblur2
that blurs low contrast areas more than strong contrast areas.
- Use a percent value to tell how much of weak area should be blurred.
The wiki contains some example stacks and results for different option sets. You might try out the shown option sets and adjust them to your own stackshot.
- Option
--cutless
needs to be adjusted for most stacks. - The radius of
--cutmorph
often needs to be adjusted. - Options
--darkness
--saturation
sometimes need an adjusted weight.
This option sets proved to work well for several macro stackshots:
-
--fft --darkness=w10 \ --maskfft \ --cutwave --cutbg --cutalpha=p-25,P150
-
--blur=s0.3,S0.6 --blur=s1,S2 --blur=s2,S3 --saturation=w25,level \ --maskwave=p5 --maskstat=r6,Mean --masklevel=t5 \ --cutless=p20 --cutwave=p75 --cutmorph=r3,R1,Erode
In some cases it makes sense to add --finalblur
or --finalblur2
. Sometimes --darkness
is better than --saturation
.