Tuesday 14 April 2020

Re-discover the Night Sky #2: stacking images in Gimp

Stacking time-lapse photos of the night sky allows you to create 'star-trail' images.

It is possible to get good results using Gimp by selecting the appropriate layer mode.

This post also describes how I hacked one of the existing Gimp scripts.

In my last post I described my initial attempts to produce star-trail images.

how to stack

Once you have a series of time-lapse images, these can be processed in Gimp (I'm using v2.10.14) to produce a final image as follows:-
  1. Open the images as Layers: menu File > Open as Layers... > then select all the photos in a sequence.
  2. For each image/layer in the Layers dialog, change the Mode from "Normal" to "Addition".
  3. Create a single layer image: menu Image > Flatten Image 
  4. Adjust Levels: menu Colours > Levels... > select Logarithmic Histogram. Slide markers to edges of histogram for each Channel; Value, Red, Green, & Blue.

Hopefully that should give you a nice image, but there is a problem with the histogram above. Although I don't know the details of the layer mode Addition, its clear that the software basically either adds together the pixel values in each layer, or a percent of the pixel values.

So if the photo exposure settings result in a grey rather than solid black background, the pixel value additive affect of the Addition layer mode can create a very light (and noisy) sky background.

I found that the end result with the current Addition layer mode was better than that obtained using the legacy version of layer mode Addition. When you use menu FX-Foundary > Multi-Layer Tools > Edit Attributes of Layers... > Addition the script changes the layer mode for all selected layers to Addition (l) which is a legacy version of Addition. I hacked a copy of this script to use the current Addition layer mode as described at the end of this post.

But the simple message here is to get the exposure right when you take the photo, and then it may not be so important which Addition layer mode you use. Here is a histogram for one photo from a sequence of 10 shots which were better exposed than the previous example...

...and this is the resultant image from 10 photos from the same sequence...

adjusting Threshold

The threshold control may be of interest when editing night-sky photos. It makes every pixel above the threshold brighter, and every pixel below the threshold darker.

compare this image with the version above

This is the same image as the previous one, but it reveals more stars.

And in the next image, I've used 'threshold' very aggressively to show (what may be) a faint meteor.

hacking the script to change the layer mode

There is already a script accessible from menu FX-Foundary > Multi-Layer Tools > Edit Attributes of Layers... which allows you to change the layer modes for all (or a selection of) layers. Unfortunately this script is quite old and only selects legacy layer modes. I decided to hack it, just to select the current Addition mode.

The original script, written by Daniel Bates, is located on your Linux machine here: /usr/share/gimp/2.0/scripts/bates-layers-attributes.scm

The first step is to copy this file to: /home/steve/.config/GIMP/2.10/scripts
(...note: your user name may not be steve) then rename the file, maybe: steves-layer-attribs.scm

Each layer mode seems to be referenced by a numerical index (0 = Normal(legacy), 1 = Dissolve (legacy), ...7 = Addition(legacy)). The new Addition mode = 33, so this is the number I want to hack into Daniel's script.

These are the lines in the original script that I changed

The first modification is to change the script definition to make it unique, so I just change "attributes" to "attribs" in three places.

Define script...

...register script...

...and also change the title that will appear in the menu to: "Steves Edit Attribs of Layers..."

OK, spot the typo

Disable all toggles except "Edit layer modes?" and remove all layer modes except Addition...

...and fix the layer mode selection to 33 (the new Addition mode)

So with this script, I can set any number of layers to Addition with just a few clicks of the mouse. The bottom layer (referenced as layer 1) can be left in Normal mode, but it doesn't seem to make any difference.

Script Update: May 2020

I eventually added 'Threshold' settings and tidied up my script.

...and here is the script which you can copy and paste into a text file and add to your Gimp scripts, if its of any interest:-

; The GIMP -- an image manipulation program
; Copyright (C) 1995 Spencer Kimball and Peter Mattis
; This script can be used to stack a number of night-sky timelapse photos
; and separate flying objects from stars. It changes the layer mode to "Addition"
; and uses Threshold to sharply define light objects from a dark background.
; Its basically a hack by Steve Davis of another script: "Mass edit layers
; attributes script" created by Daniel Bates
; --------------------------------------------------------------------
; This script is released into the public domain.
; You may redistribute and/or modify this script or extract segments without prior consent.

; This script is distributed in the hope of being useful
; but without warranty, explicit or otherwise.

; Define Script

(define (script-fu-stack-astro-layers theImage theDraw ELMcheck theLayerMode THRcheck lowerThreshold upperThreshold)

; Define Variables

    (theNumber 0)
    (theRepeat 0)
    (theName 0)
    (theLayerRef 0)
    (theLayer1 1)
    (theLayer2 2)
    (theLayerVisible 0)
    (theLayerName "sky")

; If the end layer is set below the start layer create an error message and terminate
(if (> theLayer1 theLayer2)
        (set! theLayerRef (car (gimp-message-get-handler)))
        (gimp-message-set-handler 0)
        (gimp-message "Error: End layer number must be set higher than start layer number!")
        (gimp-message-set-handler theLayerRef))
        ; Begin an undo group
        (gimp-image-undo-group-start theImage)
        ; Get the number of layers in an image and set to a variable
        (set! theNumber (car (gimp-image-get-layers theImage)))
        ; If layer2 is set above total layers change layer2 value to the total number of layers
        (set! theLayer2 theNumber)
        ; Set the repeat variable by subtracting the user input values from the total number of layers
        (set! theRepeat (+ (- theLayer2 theLayer1) 1))
        ; Adjust the value received for layer mode for direct input
        (if (> theLayerMode 1)
            (set! theLayerMode (+ theLayerMode 1)))

    ; Adjust the value received for visible for direct input
    (if (= theLayerVisible 0)
        (set! theLayerVisible 1)
        (set! theLayerVisible 0))

    ; Set up variable for setting active layers and attributes
    (set! theLayerRef (cadr (gimp-image-get-layers theImage)))
    ; Alter theNumber for use in setting active layers and attributes
    (set! theNumber (- theNumber (- theLayer1 1)))
    ; Begin loop and continue while repeat is higher than zero
    (while (> theRepeat 0)
        ; Edit layer name if requested by the user
        (gimp-drawable-set-name (aref theLayerRef (- theNumber 1)) (string-append theLayerName "#1"))
        ; Edit layer mode if requested by the user
        (if (= ELMcheck TRUE)
            (gimp-layer-set-mode (aref theLayerRef (- theNumber 1)) 33))
        ; Edit layer visible property if requested by the user
        (gimp-drawable-set-visible (aref theLayerRef (- theNumber 1)) theLayerVisible)
        ;apply Thresholds is requested
        (if (= THRcheck TRUE)
            (gimp-drawable-threshold (aref theLayerRef (- theNumber 1)) HISTOGRAM-VALUE (/ lowerThreshold 255) (/ upperThreshold 255) ))
        ; Alter variables ready for checking for next layer and applying to next layer
        (set! theNumber (- theNumber 1))
        (set! theRepeat (- theRepeat 1))

    ; Update visual display

    ; End undo group
    (gimp-image-undo-group-end theImage)


; Register script
(script-fu-register     "script-fu-stack-astro-layers"
            _"Steve's script to process Astro images..."
            _"change layer mode to Normal and apply Threshold to layers"
            "Steve Davis"
            "Steve Davis"
            "APR 2020"
            SF-IMAGE "SF-IMAGE" 0
            SF-TOGGLE _"Edit layer modes?" TRUE
            SF-OPTION _"New Layer Mode" '(_"Addition")
            SF-TOGGLE _"apply Threshold settings?" TRUE           
            SF-ADJUSTMENT _"lower Threshold (0-255)" '(3 1 2000 1 5 0 1)
            SF-ADJUSTMENT _"upper Threshold (0-255)" '(255 1 2000 1 5 0 1)           

(script-fu-menu-register "script-fu-stack-astro-layers"
                         "<Image>/FX-Foundry/Multi-Layer Tools")

No comments:

Post a Comment