Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

astrostack

A local AI astronomy image stacker. Calibrate, star-align, sigma-clip stack, AI-enhance, and post-process your light frames — all on your machine, with GPU acceleration when available and a classical CPU fallback when not.

  • CLI for scripted / batch use.
  • Web UI (Gradio) for interactive work, including a built-in photo editor and an in-page user guide.
  • Everything runs locally. The only network call is a one-time download of the AI model weights (~65 MB) from the official Real-ESRGAN GitHub release.

Contents


Features

  • Multi-format I/O: JPEG, PNG, BMP, WebP, TIFF (8/16-bit), FITS, and camera RAW (CR2, CR3, NEF, ARW, DNG, RAF, ORF, RW2, PEF, SRW, KDC, 3FR).
  • Auto-skip capture-software thumbnails (_thn, _thumb, _preview, _screen, _small) so they don't sneak into the stack.
  • Optional calibration with master darks, bias, and flats (multiple frames are auto median-combined into a master).
  • Frame quality analysis: per-frame star count and FWHM via DAOStarFinder + Gaussian fit, with a quality score.
  • Star-pattern alignment via astroalign, with sub-pixel phase correlation as a fallback when star detection fails.
  • Stacking: mean, median, or sigma-clipped mean (default).
  • AI enhancement: Real-ESRGAN x2 / x4 with weights downloaded on first use. Automatic CPU fallback to wavelet denoise + unsharp mask.
  • Device selection: CUDA, Apple MPS, or CPU (auto picks the best).
  • Side-by-side preview: see pre-enhance and post-AI results next to each other; cancel a long stack mid-run.
  • Persistent settings: stack method, model, device, format, etc. are remembered between sessions.
  • Editor: live preview with histogram, before/after toggle, brightness/contrast/saturation, gamma, black/white levels (global + per-R/G/B), asinh stretch, auto stretch, background neutralization, star-size reduction, sharpen, crop, built-in stretch presets, and user-saved presets.
  • In-page Guide tab documenting every control.
  • Dark theme by default; astrostack-ui --light to opt out.

Install

git clone https://github.com/evilgenius79/image-stacker
cd image-stacker
python -m venv .venv && source .venv/bin/activate
pip install -e .

For GPU users: install the matching PyTorch wheel before pip install -e . so the correct CUDA build gets pulled in. See https://pytorch.org/get-started/locally/.

Python 3.10–3.13 supported.

Earlier versions of this project depended on basicsr / realesrgan, which fail to build from source on Python 3.13 due to a packaging bug upstream. We now use spandrel instead — pure Python, loads the same Real-ESRGAN weights, no compile step. If you hit a basicsr build error, you're on an old checkout — git pull and re-run pip install -e ..


Web UI

astrostack-ui              # http://127.0.0.1:7860
astrostack-ui --port 8000  # custom port
astrostack-ui --share      # public Gradio share link
astrostack-ui -vv          # DEBUG logs

Three tabs:

  1. Stack & Enhance — upload light frames (and optional darks/flats/bias), pick a stacking method and AI model, run. Preview + download. A Quick help accordion sits at the top of the tab.
  2. Editor — non-destructive post-processing on the stacked result (or any uploaded image) with a live preview and full-resolution export.
  3. Guide — the full user guide, rendered right in the page.

CLI quick start

# Stack every supported file in lights/, save 16-bit TIFF
astrostack lights/ -o stacked.tif

# Full pipeline with calibration + 4x AI enhancement
astrostack lights/ \
    --darks darks/ --flats flats/ --bias bias/ \
    --enhance-model realesrgan-x4 \
    -o m31.tif

# Skip the AI step (pure classical stack)
astrostack lights/ --no-enhance -o stacked.fits

# Mix files and directories, save as FITS
astrostack img1.cr2 img2.cr2 lights/extra/ -o out.fits

# Force CPU
astrostack lights/ --device cpu -o out.png

# Also keep the pre-enhancement stack next to the output
astrostack lights/ --save-intermediate -o final.tif

CLI reference

astrostack INPUTS... -o OUTPUT [options]

INPUTS: one or more files or directories. Directories are scanned for
        supported extensions.

-o, --output PATH          Output path. Format inferred from extension.
    --darks PATH           Dark frame file(s) or directory. Repeatable.
    --bias PATH            Bias frame file(s) or directory. Repeatable.
    --flats PATH           Flat frame file(s) or directory. Repeatable.
    --method [mean|median|sigma]  Stacking algorithm. Default: sigma.
    --sigma FLOAT          Sigma threshold for sigma-clip. Default: 3.0.
    --sigma-iters INT      Sigma-clip iterations. Default: 3.
    --no-align             Skip star alignment.
    --no-enhance           Skip AI enhancement.
    --enhance-model [realesrgan-x2|realesrgan-x4]   Default: x2.
    --device [auto|cuda|mps|cpu]    Default: auto.
    --bit-depth [8|16]     Output bit depth for PNG/TIFF. Default: 16.
    --save-intermediate    Also save the pre-enhancement stack.
-v, --verbose              Increase log verbosity (-v INFO, -vv DEBUG).
-h, --help                 Show help.

How the pipeline works

Given N light frames:

  1. Load every frame as float32 in [0, 1]. RAW files are demosaiced with camera white balance and linear gamma so the stacker sees linear light.
  2. Calibrate (if any master frames provided): calibrated = light − bias − dark, then divide by normalised flat.
  3. Align frames 2..N to frame 1 using triangle-matched star patterns. Failure falls back to sub-pixel phase correlation (translation only). Frames whose alignment fails are dropped from the stack with a warning.
  4. Stack with sigma-clipped mean (default) — for each pixel, reject values more than σ standard deviations from the per-pixel mean, repeat sigma_iters times, then average what's left.
  5. Enhance with Real-ESRGAN. The 3-channel network runs on RGB; mono images are triple-stacked and collapsed back after. Images are tiled if they're big enough to risk VRAM / RAM pressure.
  6. Save in the format the output extension implies.

If anything in step 5 fails (no torch, no network, model load error, OOM), a classical wavelet-denoise + unsharp-mask pass runs instead so you still get a finished image.


Supported formats

Category Extensions
Camera RAW .cr2 .cr3 .nef .arw .dng .raf .orf .rw2 .pef .srw .kdc .3fr
Standard .jpg/.jpeg .png .bmp .webp
High bit depth .tif/.tiff (8/16-bit, mono or RGB)
Astronomy .fits .fit .fts

All light frames in one stack must share the same pixel dimensions. Mono and color can be mixed (mono is promoted to pseudo-RGB).


Capturing good data

A few quick rules of thumb:

  • Quantity + quality. More frames help, but throw out obvious junk (clouds, plane trails, badly tracked). Sigma-clip handles the rest.
  • Match calibration. Darks need the same exposure, ISO, and sensor temperature as your lights. Flats need the exact same optical setup (focus, rotation, filter, dust on the sensor) as the lights.
  • Bias optional. If your darks already "eat" the bias (same exposure length gives roughly the same readout baseline), you can skip master bias.
  • Expose for the noise. Don't sub-expose — bring up the histogram so the background is a few percent above zero. astrostack does not magically invent signal that wasn't captured.

The Editor tab

One-click helpers

  • Auto stretch — sets black/white/asinh from histogram percentiles. Best starting point.
  • Neutralize background — removes per-channel colour casts (light pollution etc.) by sampling the dimmest pixels per channel.
  • Built-in presets dropdown — None / Gentle / Standard / Aggressive / Extreme. One-click slider tunings.
  • User presets — save the current slider state under a name; load or delete any time. Stored at ~/.config/astrostack/presets.json.
  • Show original (Before) — checkbox flips the live preview to the unedited image for instant before/after comparison.
  • Histogram — live per-channel histogram with current black/white drawn as dashed lines.

Adjustment chain (every stage is identity at its default)

  1. Levels — black / white point with optional per-channel R/G/B offsets in an accordion.
  2. Asinh stretch0 off, 1 aggressive. The single most useful astro slider; try 0.4 first.
  3. Gamma — power curve.
  4. Brightness — additive offset in [-0.5, 0.5].
  5. Contrast — multiplier around mid-grey.
  6. Saturation0 greyscale, 1 identity, >1 boost. Ignored on mono.
  7. Star size reduction — masked morphological erosion of small bright peaks. Useful in dense fields where stars overpower nebulosity.
  8. Sharpen — unsharp-mask amount. Above ~1.5 expect ringing.
  9. Crop — margin sliders (left / top / right / bottom %).

The live preview is downsampled (longest edge ≤ 1280 px) for slider responsiveness. Export full-resolution re-runs the identical chain on the original-size image and gives you a download.

Frame quality analysis

On the Stack tab, Analyze loaded frames runs star detection and a Gaussian FWHM fit per file and shows a table of Stars, FWHM (px), Background, and a quality Score so you can spot duds or pick a reference.


Troubleshooting

Symptom Likely cause Fix
Frame resolution ... does not match reference Mixed image sizes Keep one resolution per run.
astroalign failed; falling back to phase correlation Too few detectable stars Try a different reference frame (reorder inputs), or turn off align.
AI enhancement fell back to classical Torch/CUDA missing or model download blocked Check network; or install torch; or accept the classical result.
CUDA out of memory Big image + x4 model Use realesrgan-x2, or --device cpu.
Result looks washed out Linear stack before stretch Use the Editor: raise black point, apply asinh stretch.
Tiny stars look square / grid-like Raw demosaic artefact on under-exposed frames Expose longer or disable enhance for that run.
FITS preview missing Browsers can't render FITS The UI auto-writes a PNG preview alongside.

Model weights cache: ~/.cache/astrostack/weights/. Delete to force re-download. The weight integrity is checked against ~/.cache/astrostack/weights/.manifest.json (trust-on-first-use SHA256); if a later download mismatches, the file is removed and the run aborts — delete the manifest if you intentionally want to accept a new upstream version.

User config: ~/.config/astrostack/settings.json (last-used run options) and ~/.config/astrostack/presets.json (saved editor presets). Both are plain JSON; safe to edit by hand.


Project layout

astrostack/
├── __init__.py
├── align.py       # star-triangle + phase-correlation alignment
├── calibrate.py   # master dark/bias/flat construction + application
├── cli.py         # click-based CLI entry point
├── device.py      # CUDA / MPS / CPU selection
├── editor.py      # post-processing chain + auto-stretch + presets
├── enhance.py     # Real-ESRGAN via spandrel + SHA256 verification
├── guide.py       # help content shown in the web UI
├── io.py          # multi-format load/save + thumbnail filter
├── pipeline.py    # end-to-end orchestration
├── quality.py     # per-frame star count + FWHM + quality score
├── settings.py    # persistent JSON settings + user presets
├── stack.py       # mean / median / sigma-clipped stacking
└── webui.py       # Gradio app (3 tabs: Stack, Editor, Guide)

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages