Skip to content

Setup and Parameter Guide for astro-color-stretch 

Horsehead Nebula with reflection nebula NGC2023

Setup guide for astro-color-stretch Version 1.1
Updated October 17, 2025

The following parameters are in the ‘user modifiable variables’ section of the Python program code. They are described below in functional detail with recommendations for setting.

File Functions:

dirpath – String specifying the OS path location of the input file as well as where the output files will be written.

infile – String specifying the name of the input file (filename.ext) to be processed. File types that can be processed are tif, jpg, and png. Supported data types for these file formats are uint8, uint16, and float32.

Unsigned 8-bit (uint8) files are scaled up to 16 bits (0-65535) for processing. Uint8 is, however, the least desirable data type for processing since this only scales up the limited 8-bit per channel information. Some color shift, especially in compressed jpg files, is likely. Tif files encoded in uint16 or float32 are the best choice. Stacked output files like those from Deep Sky Stacker (DSS) are normalized [0-1] float32 and are scaled to 0-65535.  All image arrays are processed using float64 math.

ftype – Output file type specifier:  0 – tif, 1 – jpg, 2 – png

write_full – Boolean, set to True to include the input parameter settings in the output file name. False writes a shortened version (infile-color-stretched.ext). Multiple runs do not overwrite previous versions. A -1, -2, -3, etc. suffix is added to successive identical file names.

plot_hist – Boolean specifying whether to plot the input file histogram to a file in the specified path, dirpath.

Image Stretching and Curves:

stretch_type – Determines the type of stretch to perform. 0 – no stretch, 1 – root-power stretch, 2 – asinh stretch.

Root-Power-Stretching:
The root-power-stretch is done according to the following:

output = (input)x     where x = 1 / root-power     (2)

rootiter – Set to 1 for a single pass stretch using the value specified in rootpower. Set to 2 for an added second pass using the value specified in rootpower2

rootpower – Value for a single pass root-power stretch or for the first pass of two.

rootpower2 – Value used for the second pass root-power stretch.


Asinh Stretching:
The asinh stretch option is done according to the following:

output = asinh(input / Kf) / asinh(Kf)     (3)

asinhiter – Set to 1 for a single pass stretch using the value specified in K1. Set to 2 to add a second pass using the value specified in K2.

K1 – Kf value used for a single pass asinh stretch or for the first pass of two.

K2 – Kf Value used for the second pass asinh stretch.

Figure 1 below shows output vs. input plots of both the root-power and asinh stretch types for representative values of both single and two pass stretches

Figure 1 - Root-power and Asinh Stretch Curves

Choosing the amount of stretch with either method is largely dependent on the quality of the input image data. Images with good SNR can work well with root-powers or Kf values of 100 or more. Much higher values in a single pass stretch start to have a diminishing effect. Consider a two pass stretch if more stretch is needed and can be tolerated. A two-pass stretch with lower first pass root-power values of 6-10 or Kf values of 30-50 followed by a second pass of either in the 2-5 range is a good place to start. 

On brighter images or those with a lot of sky glow, consider starting with a single pass stretch using much smaller root-powers or Kf values and working up from there. Such images may not tolerate a lot of stretching at all. Images with large gradients or vignetting should be fixed prior to stretching for best results. 

As to which stretch type to use, it depends upon the image and personal preference. The curves of both the root-power and asinh stretches are similar. With the right respective parameters, resulting images from each stretch type can be made to be virtually identical. The asinh curves do have a slightly ‘lazier’ slope in the lower input values which can have a slightly different effect depending on the stretch parameters and the image.

s-curves:
scurveSet for the type of curve to apply:  0 – no curves 1 – scurve1  2 – a sequence of scurve1, scurve2
3 – a sequence of scurve1, scurve2, scurve1  4 – a sequence of scurve1, scurve2, scurve1, scurve2.

The input vs. output plots of scurve 1 and scurve 2 are shown in figure 2 below. They are based on the same curve equations in rnc-color-stretch. Curve 1 crosses from below linear in the lower input range, which will have the effect of adding contrast to the lower mid-tones. Curve 2 will brighten the overall image with slightly more bias on the upper brighter parts of the image .

Choosing the right curve or curve sequence (if any) depends on the image data, amount of initial RTP/asinh stretch, and personal preference. I usually go with the more conservative curve 1 on my first run. Curve options 2, 3, and 4 progressively add more stretch if desired or tolerated.  It can take some experimentation to find the right combination of initial RTP/asinh stretch and curve sequence.

Figure 2 - Linear and s-curves

Color Corrrection and Adjustments:

Color Correction:
colorcorrect – Boolean, set to True to perform color correction.

colorenhance – Color enhancement factor when colorcorrect is True. Values greater than 1 add saturation, less than 1 decreases it.

HSV Adjustment:
HSVadjust – Set to True to do additional HSV adjustments according to the values below. These optional HSV adjustments can also be done in a post-processor. However, I have sometimes found them to be convenient for quickly comparing slightly different hue shifts or saturation levels on multiple runs.

hue_adjust – Adjusts hue from -120 to +120 degrees (0 to 360 degrees according on the standard HSV model). Zero degrees is no hue adjust.

sat_adjust – Set between 0 and 2 to reduce or increase saturation. Has a similar but stronger effect as colorenhance in colorcorrection.

val_adjust – Set between 0.1 and 2.0 to darken or lighten.

White Balance Adjustment:
White balance can also be easily adjusted in post processing. However, these adjustments can be used to ‘center’ up a white balance, giving the post-processor more range on either side for adjustment.

wb_mode – Method for adjusting white balance:
0 – None: No white balance adjustment is performed.

1 – gray-world method: Corrects general color cast (too blue or too warm) by scaling to an average gray across all
channels and scaling to adjust each channel so that its mean matches the gray average. This method generally works well for images of galaxies but not so well for more saturated, colorful objects like nebulae. 

2 – temp/tint adjustment: Adjusts white balance based on specified temp and tint factors.
temp –  > 1 warms the image, values < 1 cools the image (range 0.85 to 1.15)
tint –  > 1 more magenta,  < 1 more green (range 0.70 to 1.30)

Corrections:

Chromatic Aberration Correction:
ca_correct – Set to True to perform chromatic aberration correction. The effect is slight in order to avoid excessive color shifts and artifacts. The amount and efficacy will vary depending on the image.

Vignetting Correction:
vn_correct – Radial Vignette Correction enabled when set to True. Radial vignette correction corrects brightness falloff toward the edges using a least squares fit of intensity vs. radius. It assumes falloff is radially symmetric and smoothly varying.

vn_strength – Controls the amount of vignetting correction (range 0 to 100), representing 0% to 100% correction.

Gradient Correction:
lg_correct – Linear Gradient Correction enabled when set to True. Linear gradient correction corrects for linear gradients across the frame using a least squares fit. Gradients that can be fixed are horizontal linear, vertical linear, diagonal linear, and planar tilt (brighter in one corner, darker in the opposite). 

lg_strength – Controls the amount of gradient correction (range 0 to 100), representing 0% to 100% correction. 

Vignette correction and linear gradient correction can be applied independently or in combination, depending on the characteristics of the image. In some cases, either correction may be unnecessary or may even produce negative effects. Experimentation is needed to find what is optimal.

  • Vignette correction is most effective for images that are un-cropped or only lightly cropped. Without correction, stretched images often appear with a bright center and darker corners, making it difficult to establish a consistent post-stretch zero sky background level. Heavily cropped images typically exhibit little to no vignetting and likely will not benefit from this correction.

  • Linear gradient correction is recommended for images captured under conditions with significant sky glow or light pollution. These often exhibit a brightness gradient across the frame, typically from one edge to the other. Gradient correction can effectively mitigate this effect.

For both vignette and gradient correction, in some images a small number of values may exceed the 0-65535 range. When this occurs, the full max/min values and how many points outside this range are displayed as a warning in the printed output stream. Output values are clipped to fit in the 0-65535 range. In my experience this method has not shown any visible issues in the final output images. Reducing the correction strengths may also help.

Note too that both corrections are somewhat computationally intensive and will increase processing time. For reference, a full-size uncorrected image typically processes in 30–40 seconds on a MacBook M4 Pro. Applying vignette correction increases this to just over one minute.

Star Size Reduction –
star_reduction – set to True to perform a star reduction on the final output image. This method uses a Difference of Gaussians (DoG) to detect stars , filters out small isolated pixels, followed by masking to shrink star halo sizes.

reduction_strength – Controls the amount of star size reduction (range 0.0 to 1.0). Specifying 0 represents no star size reduction.

Sky Level Factors:

skylevelfactor  Sky level relative to histogram peak. Default of 6% (0.06) seems to work well in most cases. Lowering can help improve zero sky color shift at the risk of not finding zero sky levels. Higher levels might be needed when zero sky levels are not found.

zeroskyred, zeroskygreen, zeroskyblue – Zero sky levels for respective rgb channels (0 – 25000). These values are set to 4096 as default, which works well in most cases. However, for dark sky levels that exhibit color shift from not finding a good black point, these parameters can be adjusted. Using the box_method described below can help in finding a dark sky region to optimize black point.

setmin – Set to true to perform a set minimum in the rgb data. This brings up the base level using scaling to assure there are no really dark pixels.

setminr, setming, setminb – Minimum values used for respective rgb channels. Defaults for each channel are set to 4096.

rgbskyzero_method – Method for determining image area for setting zero sky levels.
0 – full_area:  Use the entire image area for setting the zero sky levels.
1 – restricted_area: Use a restricted window of the darkest area defined by win_width and win_height for setting the zero sky levels.

win_width – Width of box area in pixels for auto-scan for darkest region
win_height – Height of box area in pixels for auto-scan for darkest region

win_frac – Set from 1 – 10. Window steps for sliding window defined by win_width x win_height across and down the image during auto-scan for the darkest region.

Use of the rgbskyzero_method:
In most images the results from using the full image area or a restricted dark area will be virtually identical. Using the full area rgbskyzero_method  = 0  is faster and usually preferred as it does not include the added step of scanning the full image for the darkest area.

In cases where there is significant light pollution or a background bias, stretching to bring out faint details can exaggerate zero sky errors set by the estimated channel zero sky values. This will usually manifest in the dark areas as color shifts. Just running using a restricted dark sky area alone, though, will not likely improve such images. Adjustment of the individual zero sky parameters (zeroskyred, zeroskygreen, zeroskyblue)  is needed.

To help in doing this, setting rgbskyzero_method  = 1 will auto-scan the full image for the darkest area contained in the window specified by win_width x win_height in increments specified by win_frac . In addition to the normal output file, this will generate a file of just the isolated dark area as well as one of the entire image showing a box around where the dark area was found. Histograms of the original input file as well as those of the zero sky subtracted full image and dark sky area will also be written to the selected path.

The image of the selected dark region can then be evaluated as is or stretched for easier identification of dark region color shifts. Program astro-color-stretch can be used to do the stretch (with parameter rgbskyzero_method = 0) or it can be hand stretched in a post processor. The zero sky parameters can then be iteratively adjusted to find a better black point. Since astro-color-stretch runs very fast (< 1s for small dark region images), multiple runs can be done quickly to determine the optimal setting.

Choosing a win_width and win_height depends on the image. Too small an area compared to the full image results in a pixelated image with less information. Too large, and the area will likely pick up too much overall image sky glow, defeating the purpose of using a smaller dark region. By observing the general shape and size of the area that might be darkest in a given image is the best guide in determining the best size and aspect ratio. I usually start with something at least in the neighborhood of 700 pixels on a side for a full-frame 45.6 MP image.

For the auto-scan, a win_frac  = 1 steps the full window across image without any overlap. This is the fastest and least accurate scan but works well in images with larger dark areas relative to the window size. Setting win_frac  = 10  increments the window scan by 1/10 of the window height and width. This is more accurate for finding the darkest area but takes a little longer. In practice this still scans very quickly for even large 45.6MP full frame images.

Running astro-color-stretch

Program astro-color-stretch is a single Python file and is available in the astrophotography software downloads page. It is provided here free and open source according to the license agreement in the downloads page. Since this program is an adaptation of Roger Clark’s original rnc-color-stretch program, all previous copyright and license terms in his original license also apply.

The program was developed using PyCharm. I highly recommend this IDE to load and run astro-color-stretch for first time and even experienced users. It is reliable and easy to use. In order to run astro-color-stretch, a number of imports are required. Modules os, math, sys, and time are built-in so they should already be included in the current version of Python. CV2 and NumPy, however, must be installed if not already done so by the user. This can be done either with pip install via a console window or from within PyCharm by going to PyCharm “settings…”. Under your project name, find “Python Interpreter” and then click the “+” (install) symbol. This will pull up a window where you can search for CV2 and NumPy to install. There are a number of internet resources that can help with these installations or debug any issues.

As I have not yet written a GUI or implemented an input file method for parameter input, the program parameters must be modified directly in the “user modifiable variables” section near the top of the program code. Comments in the code and the information provided above should easily guide the user. Beyond that, no programming knowledge of Python is required to run astro-color-stretch.

I have only run astro-color-stretch on Mac OS but it should run fine in Windows provided that the dirpath variable is set for the correct Windows path syntax. I am working on a Win 11 VMware virtual machine but have so far found it to be far too unstable to load and verify astro-color-stretch in Windows. Any feedback on issues or modifications needed with running this code on Windows are welcome via an email or in the comments.

Download
astro-color-stretch-1.1 can be downloaded here on the Astrophotography Software Page.

Additional Astrophotography Resources
Main Astrophotography Page