HaloStack

by Panu Lahtinen (pnuu a iki fi)

This page is obsolete. Check documentation page for the new version.

Newest Windows binary available here.

Sama suomeksi täällä.

Contents:

HaloStack is a simple, platform independent image stacking software mainly designed for stacking ice halo photographs. HaloStack is available only as commandline version, but a graphical user interface will be available some day. A simple image alignment can be used, and it works with photographs taken with semi-transparent blocker in front of the Sun. The alignment works quite well also with images taken from tripod without a blocker, but the alignment takes much more time as the alignment area is much larger.

Output images are saved in PNG format. All average stacks are 16-bits/channel whether the used images have been 8-bit or RAW image data with higher bit-depth. Other image stacks are saved with the same bit-depth of the original images, ie. output will be 8-bits/channel for JPG-images and 16-bits/channel for input image files with higher than 8-bits/channel color data (eg. RAW and 16-bit TIFF files).

For very basic use, only Python with Numpy and PythonMagick libraries are required.

Additional external libraries are needed for some features:
  • UFRaw software for RAW-image support via PythonMagick. This feature has not been tested on Windows.
  • h5py HDF5 Python library for median stacking
  • SciPy python library for image rotation

Download and install

Ubuntu

Install by extracting the archive to a suitable directory. See usage examples below.

Download HaloStack v0.1.2 Python scripts: .tar.gz, .zip

Open a terminal and paste this command to install prerequisites:
sudo apt-get install python python-numpy python-pythonmagick ufraw python-h5py python-scipy

Windows

In Windows, there's two choices. If you are not going to modify the scripts, it is advisable to use the bundle with all dependencies:

Download HaloStack 0.1.1 bundle for Windows: 32-bit, 64-bit

Other choice is to download the Python scripts (see installation instructions for Ubuntu) and install the dependencies listed below.
  • Python (versio 2.x)
  • Numpy
  • PythonMagick (select the same version as your Python installation)
  • h5py (optional, required for median stacking)
  • SciPy (optional, required for image rotation)
  • UFRaw (not tested on Windows)

TODO

These features are planned, but they have not been implemented yet.

  • Graphical user interface
  • log-file

Commandline parameters

-a FILE, --average-stack FILE
    Calculate average of the images and save it as FILE in PNG format
    with 16-bits/color.
-m FILE, --max-intensity-stack FILE
    For every pixel location, select the pixel with the highest
    overall brightness (R+G+B is largest). Image is saved as FILE in
    PNG format with the same bit-depth as the input images.
-M FILE, --max-deviation-stack FILE
    For every pixel location, select the pixel where standard
    deviation between the R/G/B colorchannels is greatest. Image is
    saved as FILE in PNG format with the same bit-depth as the input
    images.
-c FILE, --max-color-diff FILE
    For every pixel location, select the pixel with greatest color
    separation, that is max(R,G,B) - min(R,G,B) has the highest
    value. Image is saved as FILE in PNG format with the same
    bit-depth as the input images.
-e FILE, --median FILE
    Calculate median value for each pixel location. With many images
    this will be very slow and heavy on harddisk read/write
    operations. Image is saved as FILE in PNG format with the same
    bit-depth as the input images.
-u R,A[,S[,T]], --pre-usm R,A[,S[,T]]
    Apply unsharp mask (USM) filter to the images before stacking.
    R - radius of the mask in pixels
    A - amount of the sharpening
    S - sigma, or radial weight of the mask [optional]
    T - threshold, only pixels with higher value than this will be
        sharpened [optional
-U R,A[,S[,T]], --post-usm R,A[,S[,T]]
    Apply unsharp mask (USM) filter to the completed stacks as the
    last operation before saving. For parameter definitions, see
    above.
-b FILE, --base-image FILE
    Image used as a reference for alignment and inter-image brightness
    normalization. If omitted, the first image will be used as a
    reference.
-r x,y,s, --align-reference x,y,s
    Align images by finding the most similar location compared to a
    reference. The reference area is defined by center coordinates
    (x,y) and area size s. Reference area is a square 2s+1 by 2s+1
    pixels. The origo (0,0) of the pixel coordinates is at the
    top-left corner of the image. By default, the reference data are
    taken from the first image. If base image has been set with -b
    FILE, the reference data are selected from that image.
-s x1,y1,x2,y2, --align-search-area x1,y1,x2,y2
    To speed-up alignment calculations, the search area can be limited
    by giving top-left (x1,y1) and bottom-right (x2,y2) corners of an
    area that contains the alignment point in all images. The origo
    (0,0) of the pixel coordinates is at the top-left corner of the
    image.
-n NUM, --normalize NUM
    Normalize image intensities before stacking. Number NUM defines the
    level to adjust the median of the image to. If NUM is set to zero,
    images are normalized to the first image or, if defined with -b,
    to selected base image.
-N x1,y1,x2,y2, --normalize-area x1,y1,x2,y2
    Calculate the normalization values from the area defined by
    top-left (x1,y1) and bottom-right (x2,y2) corners. The origo (0,0)
    of the pixel coordinates is at the top-left corner of the image.
-t NUM, --correlation-threshold NUM
    Require the correlation (R^2) between reference and the best fit
    to be atleast NUM. Correlation can be within range from 0 to 1,
    where 1 is perfect fit. Default is to allow all images to be
    included in the stack, ie. -t 0.
-R X1,Y2,X2,Y2,S, --rotate-points=X1,Y2,X2,Y2,S
    Define two square-shaped areas (2S+1 x 2S+1) that are used to
    rotate images so that these points are on a horizontal
    line. Squares are centered at (X1,Y1) and (X2,Y2). The origo (0,0)
    of the pixel coordinates is at the top-left corner of the image.
-O STR, --output-images STR
    Save individual frames as PNG files. These files can be used to
    speed up the processing if RAW image files are used and stacking
    needs to be done again. This option can also be used so that it is
    possible to hand-adjust single images if the alignment process
    fails.

Usage examples

Below examples assume that you are using pure Python version. If you are using the bundled version for Windows, you need to replace "python halostack.py" with plain "halostack". In linux it is possible to run the stacker without the extra call to Python interpreter, ie. "halostack.py" is sufficient.

  • Calculate average of every JPG image in the current directory and save it as average.png.
        python halostack.py -a average.png *.JPG
    
  • For every pixel-location, select the pixel with maximum overall intensity:
        python halostack.py -m maximum_intensity.png *.tiff
    
  • For every pixel-location, select the pixel with maximal separation between brightest and dimmest color value in the R/G/B channels
        python halostack.py -c maximum_color_difference.png *.Png
    
  • For every pixel-location, select the pixel pixel with largest standard deviation in the R/G/B channels:
        python halostack.py -M maximum_color_deviation *.jpg
    
  • Calculate median value for every pixel-location. Requires h5py Python library:
        python halostack.py -n median.png *.TIF
    
  • Align images using one alignment point and calculate the average of these images. Here, alignment point is at x=300 and y=1203 is 25-by-25 pixels (2n+1) in size. Pixel coordinates are defined so that the top-left corner of the image is (0,0). This version is slow, as it searches the best fit from the whole image area. Alignment reference data is taken from the first image.
        python halostack.py -a average.png -r 300,1203,12 *.jpg
    
  • Same as previous, but limit the search area with top-left (x1,y1) and lower-right (x2,y2) pixel coordinates of the area used to search for the correct alignment point. This area should be set large enough to cover the correct locations in all of the images being stacked.
        python halostack.py -a average.png -r 300,1203,12 -s 250,1150,400,1300 *.tif
    
  • Same as previous, but the alignment point has been determined from image "image42.tif".
        python halostack.py -a average.png -r 300,1203,12 -s 250,1150,400,1300 -b image42.tif *.tif
    
  • Enhance the images with unsharp mask (USM) before stacking. USM will be applied before any other operation.
        python halostack.py -a average.png -u r,a,s,t *.jpg
    
    where
        R = radius of USM filter, eg. 40
        A = amount of USM filter, eg. 2.5 (same as 250 % in Photoshop)
        S = sigma of USM filter (radial weight), defaults to r/2, optional is
            threshold (below) has not been defined
        T = threshold pixel-value, pixels with lower intensity than this will
            be excluded, defaults to zero, optional
    
  • Apply USM after the stacking. This will be the last operation done before writing the image file. Note that sigma and threshold values have not been defined, and default values (s=r/2, t=0) will be used.
        python halostack.py -a average.png -U 25,2.5 *.jpg
    
  • Normalize all images to brightness determined from the first image. Normalization is performed before alignment and stacking.
        python halostack.py -m maximum_intensity.png -n 0 *.tif
    
  • Normalize all images to brightness determined from area given by bounding-box with upper-left corner at (x1: 300, y1: 300) and lower-right corner at (x2: 400, y2: 400) of base image "image42.tif". Normalization will be applied so that the median level on each images on this area will be the same.
        python halostack.py -m max_int.png -b image42.tif -n 0 -N 300,300,400,400 *.tif
    

Test material

Here you can find some example images to test how the stacking works.

  • Images by Marko Riikonen from a pyramid halo display around the Sun on April 20, 2012: link
    • Example command (using the Windows bundle):
    • halostack -a average.png -r 772,648,9 -s 750,620,795,670 DSC_*
  • Images by Marko Riikonen from a surface halo display on April 9, 2012: link
    • Example command (using the Windows bundle):
    • halostack -m maximum.png -r 615,497,9 -s 590,470,640,515 U*jpg
  • Images by Panu Lahtinen with bright 22 degree upper tangent arc on April 23, 2012. Taken without a blocker, so note the large (40 pixels in each directions from the Sun) alignment area: link.
    • Example command (using the Windows bundle):
    • halostack -a average.png -r 405,320,40 -s 370,290,440,350 *jpg