The front door to SASpro's planetary stacking pipeline — opens SER, AVI, MP4/MOV/MKV videos and image sequences, scrubs through frames, defines the ROI and surface anchor, previews debayering and tone adjustments, and hands off to the Stacker or the Batch processor. Nothing is stacked here — this is the setup stage.
Click Open SER/AVI/Frames… and either pick a single video file or multi-select images to load as a sorted sequence. Supported formats:
| Category | Extensions | Notes |
|---|---|---|
| SER video | .ser | Native planetary format; carries pixel depth, color ID, timestamps. |
| Other video | .avi, .mp4, .mov, .mkv | Decoded frame-by-frame. For AVIs an FFT-based auto-detect looks at frame 0 and warns if it finds a Bayer mosaic (see §6). |
| Image sequence | Any mix of .tif, .tiff, .fit, .fits, .png, .jpg, .jpeg, .bmp, .webp | Multi-select in the dialog, sorted alphabetically. Treated as sequential frames. |
After loading, the info strip across the top shows the file name, dimensions, frame count, bit depth, color name and whether SER timestamps are present. The last-used folder is remembered via QSettings so the next Open starts there.
The right half of the window is a QGraphicsView showing the current frame with full continuous zoom and pan.
On the first opened frame the view auto-fits; after that your current zoom and pan are preserved as you scrub, so you can zoom in on a feature and watch it drift across frames.
The frame slider under the top toolbar lets you jump to any frame; the N / Total label on the right shows which frame you're on (1-indexed). Play cycles through at roughly 30 fps and loops at the end; press again to pause. Scrubbing redraws immediately with all current preview options applied (debayer, ROI crop, autostretch, brightness, gamma, overlays).
The Trim panel on the right lets you keep only a contiguous frame range as a new SER file.
Trim is useful for cutting out satellite-passing frames, dropped-sync frames at session boundaries, or breaking a huge SER into manageable chunks before stacking.
The ROI is the crop that gets passed down to the Stacker. Define it two ways:
All ROI coordinates are forced to even values (both origin and size) to preserve the Bayer phase — cropping a Bayer SER on an odd boundary would scramble the RGGB mosaic. See §13.3 for the exact clamping rule.
If the source is a raw Bayer mosaic (common for mono planetary cameras shot with an OSC-style Bayer filter), SASpro debayers it on the fly for preview. Controls:
AUTO, RGGB, GRBG, GBRG, BGGR. For SER, the pattern comes from the file header. For AVI/MP4, the SER header isn't there, so AUTO defaults to RGGB after an FFT check.When an AVI/MP4/MOV/MKV is loaded with Bayer pattern AUTO, SASpro examines frame 0 to decide if it's a raw mosaic. The test compares the FFT energy at the four Nyquist corners (which a Bayer checkerboard concentrates energy at) against the rest of the spectrum. If the ratio is high, the file is flagged as Bayered and the dropdown is defaulted to RGGB with an amber warning: “Bayer pattern detected — defaulting to RGGB. If colours look wrong, change the Bayer pattern dropdown to match your camera sensor.” See §13.2 for the math.
Three preview-only controls make the frame actually visible — they do not affect what gets passed to the Stacker and, importantly, they do not affect the planetary centroid detection either (see §10).
target_median = 0.25 via SASpro's shared linked autostretch (mono or RGB). Useful for faint deep-sky-adjacent planetary subjects or for seeing noise structure during focus checks.[-0.25, +0.25], clipped.[0.30, 3.00]; 1.00 = no change.The order is autostretch (if on) → brightness → gamma. The result is clipped to [0, 1] and shown.
Pick how the Stacker will align frames downstream:
| Mode | What it tracks | Use for |
|---|---|---|
| Planetary | The brightness centroid of pixels above a threshold. | Planetary discs on a dark sky (Jupiter, Saturn, Mars, Venus, lunar craters at high mag). |
| Surface | A user-picked anchor patch via NCC + phase correlation. | The Moon, Sun, or any object filling a large fraction of the frame where no clean disc edge exists. |
| Off | No alignment — frames are stacked where they land. | Pre-aligned data (e.g., an aligned SER exported from a previous Stacker run) or static test cases. |
Changing modes updates the preview overlays and the anchor-label status immediately. Surface mode without an anchor shows a red REQUIRED warning until you set one.
Surface tracking needs an anchor — a small, high-contrast patch (a crater rim, a prominent sunspot, a filament tip) that SASpro can lock onto across every frame. To set it:
Ctrl+Shift+drag a rectangle on the preview (on macOS: ⌃⇧-drag — the Control key, not Command). A blue rubber-band distinguishes the anchor from the green ROI rectangle. On release, the anchor's position and size are stored in ROI-space, and the anchor label at the bottom-right turns green with x, y, w, h.
While Surface mode is active, the anchor is drawn as a translucent blue outlined rectangle on top of the live preview so you can see what's actually being tracked. If you move the ROI, the anchor overlay still renders correctly — see §13.4 for how ROI-space is defined.
In Planetary mode, SASpro draws a bright yellow crosshair at the live-computed centroid of the current frame, so you can see exactly what the tracker thinks the planet's centre is before you commit to stacking. If the crosshair is on the wrong feature or wandering, your detection parameters need tweaking:
[0, 1] before thresholding. Useful for very dim subjects where the raw signal never approaches the default threshold. Leave off for typical bright targets.The crosshair is drawn on the pre-tone (pre-brightness, pre-gamma) image, so the tracker's centroid is independent of your preview settings — cranking gamma for viewing doesn't shift the lock point. These same values are passed to the Stacker when you open it (§12).
The Keep % spinbox (0.1 to 100, default 20) tells the Stacker what fraction of frames to actually integrate, ranked by the quality metric. 20–30% is typical for planetary; higher for well-tracked sessions on steady nights. This value is forwarded to the Stacker and shown on its quality graph — you can still adjust it there by dragging the vertical cutoff line.
The preview and I/O pipeline, in order.
SER, AVI/MP4/MOV/MKV and image sequences all go through a single PlanetaryFrameSource interface returned by open_planetary_source. The interface exposes a meta block (width, height, frames, pixel depth, color name, source kind, optional timestamp flag) and a get_frame(idx, roi=…, debayer=…, to_float01=…, force_rgb=…, bayer_pattern=…) method. The frame cache is sized by the cache_items argument; 10 is the default, which is enough for smooth scrubbing without burning RAM.
For AVI-family files loaded with Bayer pattern AUTO, SASpro reads frame 0, takes a centred 256×256 crop, subtracts its mean (removes DC), and computes the 2D FFT magnitude:
where the four Nyquist corners of the shifted spectrum are averaged (3-pixel neighbourhood each), the DC region (8-pixel neighbourhood around centre) is excluded from the “rest”, and the ratio ρ is thresholded at 2.5. A raw RGGB mosaic concentrates energy at those corners due to the alternating-pixel grid; a true colour (already debayered) frame does not. Values above the threshold trigger the warning and default-to-RGGB behaviour described in §6.
Both the ROI origin and size are bitwise-ANDed with ~1 to force even values, and the ROI is clamped to lie entirely inside the source image. Minimum size is 2×2. This preservation of the Bayer phase is critical: an odd-pixel crop would make the top-left pixel of the ROI a different filter colour than the top-left of the full frame, and the debayerer would produce the wrong colours. The clamp runs on any manual spinbox edit and on every rubber-band release.
The surface anchor is always stored in ROI-space coordinates (0 to ROI width × 0 to ROI height). When ROI is enabled, the displayed image is already the cropped region, so the anchor rectangle is drawn directly on it. When ROI is disabled, ROI-space is equal to full-frame space, so the same coordinates still render correctly. This means toggling ROI on and off never invalidates the anchor — it stays locked on the same real-world feature.
Internally, the gesture coordinates come from the viewport, are translated through the preview widget's position to displayed-image pixel coordinates, and then (if ROI is on and the drag was for a new ROI) back-converted to full-frame coordinates for the ROI spinboxes. Anchors never need that back-conversion because they stay in ROI-space.
The preview tone sequence is autostretch (optional) → brightness offset → gamma power, with a final clip to [0, 1]:
with b the brightness offset (-0.25 to +0.25 scaled from the slider) and γ the gamma (0.30 to 3.00 scaled from the slider). The pre-tone image is stashed in _last_disp_arr for use by the centroid overlay, so a tweak to brightness or gamma updates the display but doesn't move the yellow crosshair.
In Planetary mode, SASpro computes the centroid on the pre-tone ROI-cropped mono image via the shared compute_planet_center:
where τ is the threshold slider (as a fraction of max intensity after an optional pre-normalize), and the image is pre-smoothed with a Gaussian of σ = 1.5 to suppress single-pixel hot spikes. The resulting (x_c, y_c) is mapped from image coordinates back to pixmap coordinates for drawing the 10-pixel yellow crosshair.
FITS, TIFF, PNG, JPEG, BMP and WebP go through SASpro's load_image helper directly. When loaded as an image sequence, the files are sorted alphabetically; the viewer treats each file as one frame of a virtual video. For FITS files that are also Bayer mosaics (via the BAYERPAT header), debayering follows the usual Bayer pattern dropdown.
Overlays are drawn after the pixmap is scaled to the current zoom, so the crosshair size and anchor rectangle thickness stay constant on screen regardless of zoom level — which keeps the crosshair readable at both 1:1 and 1600%. The surface anchor is drawn as a 3 px blue outlined rectangle with a 30/255 alpha fill; the planetary centroid as a 10 px yellow crosshair with a 2×2 pixel centre dot.
COLOR_BayerRG2RGB et al.), resampling routines, warp and FFT-magnitude operations used in both preview rendering and the Bayer auto-detect; FFmpeg (via SASpro's platform decoder) decodes AVI/MP4/MOV/MKV container frames; the SER reader is SASpro's own implementation of the Lumenera SER v3 spec. NumPy provides the array engine and PyQt6 / Qt QGraphicsView the UI framework and interactive preview. The Planetary Stacker and Batch Planetary Stacker, which this viewer feeds, are documented separately.