3D Projection

Turn flat astro images into stereo pairs, wiggle animations, red/cyan anaglyphs, interactive HTML 3D, pseudo-surface point clouds, and top-down galaxy views — all from a single sub.

The fun one. This tool takes a 2D image of a planet, moon, or galaxy and gives you six different ways to see it in 3D: side-by-side stereo pairs (parallel or cross-eye), rapid wiggle animations, classic red/cyan anaglyphs for 3D glasses, interactive Plotly-based sphere HTML you can rotate in a browser, pseudo-surface point clouds that treat image brightness as height for lunar / solar / nebula detail, and — perhaps the most useful scientific option — a galaxy polar-view deprojection that takes a near-edge-on galaxy and lets you look straight down on its disk. The math underneath is standard computer graphics (sphere reprojection, orthographic unprojection, ellipse foreshortening); the fun comes from applying all of it to the frames you already imaged. Original work by Franklin Marek for SetiAstro Suite Pro.

1. The six output modes

Pick one from the top Output dropdown:

ModeWhat it doesHow to view
Stereo (Parallel) L | RSide-by-side left-eye-left, right-eye-right. Image is reasonably sized to free-fuse.Diverge your eyes slightly (as if staring past the screen) until the two images fuse into one 3D image.
Stereo (Cross-eye) R | LSide-by-side right-eye-left, left-eye-right. Same source, swapped output.Cross your eyes (as if looking at your nose) to fuse. Easier for most people than parallel.
Wiggle stereoRapidly alternates L and R views at the Wiggle period you set.Just watch — your visual system interprets the motion as depth. No glasses, no eye-crossing. Share as GIF or MP4.
Anaglyph (Red/Cyan)Classic 3D-glasses composite — red channel is left-eye luminance, cyan is right-eye luminance.Red/cyan paper glasses. Looks washed out without them, pops into 3D with.
Interactive 3D (HTML)Exports a Plotly-based 3D sphere (or point cloud) you can rotate, zoom and pan in any browser.Opens in your default browser. Standalone HTML, works offline, shareable.
Galaxy Polar View (Top-Down)Takes an inclined galaxy and reprojects it as if viewed face-on from the galactic north pole.Just view normally. The deprojected image lives at native resolution for stacking into comparisons.

The three stereo modes (Parallel, Cross-eye, Wiggle) and the Anaglyph all share the same underlying stereo-pair generation — they just differ in how the pair is composited for display. Interactive 3D and Galaxy Polar View generate their outputs via different pipelines.

2. The four planet types

TypeWhen to use
Normal (Sphere only)Any planet, moon, or round body where you want the body treated as a sphere. Mars, Venus, Jupiter without rings, Mercury, moons.
Saturn (Sphere + Rings)Saturn — adds an elliptical annulus for the rings with front/back occlusion by the planet body.
Pseudo surface (Height from brightness)Lunar craters, solar granulation, or any surface where image brightness correlates with 3D height. Also works beautifully on nebulae for an artistic "cosmic landscape" effect.
Galaxy (Disk deprojection)Edge-on or inclined galaxies where you want to see the disk structure from above. Also exposes PA / tilt controls that let the Interactive 3D export produce a proper tilted galaxy mesh.

The planet type and the output mode combine freely: for example, "Saturn + Interactive 3D" gives you a Plotly sphere with real ring geometry you can orbit, while "Pseudo surface + Wiggle" gives you a swaying heightmap of your lunar close-up.

3. Common workflow

  1. Open the dialog on an active image.
  2. Pick Output and Planet type from the two top dropdowns.
  3. Set Strength (°) — the stereo parallax angle. 6° is the sweet spot for most planets; 2-3° for subtle depth, 10-15° for exaggerated. Only matters for the stereo and anaglyph modes.
  4. Review the detected disk if the "Review / adjust detected disk" checkbox is ticked (default). The disk-adjust dialog opens with an automatic estimate — nudge or redraw as needed.
  5. Click Generate. The preview window opens with your result.
  6. From the preview: Save Still, Save Wiggle (if wiggle mode is active), or Push to New Document to drop the result into a SASpro doc for further processing.

4. The disk-adjust dialog

When "Review / adjust detected disk" is enabled, Generate pauses to let you confirm the disk location. The dialog shows the image with a green circle (and, for Saturn / galaxy / planet types, an ellipse overlay with PA and tilt handles).

Disk-adjust controls.
Ctrl+Click+Drag — move the circle center.
Arrow keys or ▲▼◀▶ buttons — nudge by the configurable px step.
Radius slider / spinbox / Radius ± buttons — resize the circle.
🎯 Auto-detect disk — WinJUPOS-style ellipse fit on the brightest blob. Updates center, radius, and (for ellipse modes) PA and tilt all at once. Great starting point.
Ring/Disk PA (deg) — rotate the ellipse. For Saturn, this is the ring plane's angle in the image; for galaxy, the galactic disk's major-axis angle; for planet-type with axis alignment, the rotation axis direction.
Tilt (b/a) — ellipse minor/major ratio, 0.05-1.0. 1.0 = circle (face-on); smaller = more edge-on.
Outer / Inner factor (Saturn only) — ring radii in units of planet radius.
Zoom controls — Fit, 1:1, +/- for close inspection.
Use This Disk — accept and continue to generation.

5. Backgrounds and parallax

The background behind the planet can be configured three ways:

The Background depth slider controls how much the background participates in the stereo parallax, as a percentage of the planet's parallax:

Background depth and Saturn. For Saturn specifically the depth sign is auto-flipped internally, so a positive slider value keeps the stars visually behind the ring plane as you'd expect, matching your sense of "I'm looking at Saturn with a star field behind it".

6. Workflow recipes

Classic planet stereo with 3D glasses. Planet type: Normal. Output: Anaglyph. Strength: 6°. Turn Starfield on (density 0.03), background depth 25%. Click Generate. Put on red/cyan glasses, look at the preview. The planet pops forward of the stars; you should see curvature in the globe immediately.
Saturn with rings in 3D. Planet type: Saturn. Output: Anaglyph (or Wiggle for shareable animation). In the disk-adjust dialog, click Auto-detect — this usually catches Saturn's ellipse PA automatically. Fine-tune the ring tilt until the ring major axis matches your real image. The front half of the ring will occlude behind-the-body, the back half will emerge in front, giving a solid 3D feel of the ring plane geometry.
Shareable GIF for social media. Planet type: Normal (or Saturn). Output: Wiggle stereo. Strength: 8°. Wiggle period: 150 ms (a comfortable blink rate). Click Generate — the preview starts wiggling. Click Save Wiggle, pick GIF, save. The resulting file loops forever and shows depth without needing glasses or eye-crossing. Share directly.
Lunar craters as a 3D landscape. Planet type: Pseudo surface. Output: any (Anaglyph works well). Depth gamma 1.5 to emphasize crater rims, depth blur 1.0 to reduce noise, invert off (bright = closer, so sunlit rims come forward). The result is a tilt-shift-looking terrain view, excellent for high-detail lunar images.
Nebula "cosmic landscape". Planet type: Pseudo surface. Output: Interactive 3D (HTML). Height from: Dual (brightness + saturation). Max points: 500000. Click Generate, pick a save path, and the HTML opens in your browser — bright nebular features become hills, dust lanes become valleys, and the whole thing rotates in your browser. Not scientifically meaningful (brightness isn't actually height for a nebula), but visually stunning.
Galaxy polar view — see a tilted galaxy from above. Planet type: Galaxy. Output switches automatically to Galaxy Polar View. In the disk-adjust dialog, align the ellipse overlay to the galaxy's projected shape: PA to the major axis, tilt (b/a) to the apparent axis ratio. Click Auto-detect to get a good starting fit, then fine-tune. On Generate, the galaxy is reprojected into a face-on view — you can now see spiral arm structure that was foreshortened in the original. This is the fun scientific one: you can take your edge-on M31 or NGC 4565 and reveal spiral structure that your line-of-sight was hiding.
Interactive 3D sphere for a web page or presentation. Planet type: Normal (or Saturn for rings). Output: Interactive 3D (HTML). Click Generate, pick a save path. The resulting .html file is standalone (just needs internet for the Plotly JS, which it pulls from CDN) and lets anyone rotate, zoom, and inspect your planet from any angle. Drop it in a blog post, email it, keep it on your observing laptop as a 3D reference.

7. Interactive 3D exports — details

The HTML export has three distinct forms depending on planet type:

8. Technical details

The projection math, the ring geometry, the pseudo-surface heightmap, the galaxy deprojection, and the anaglyph composition.

8.1 Sphere reprojection (the core of planet stereo)

The planet in your image is a 2D disk — the orthographic shadow of a sphere. To make stereo, we first unproject each disk pixel back onto the sphere, then rotate the sphere by ±θ around the vertical axis, then project back to pixels for the left and right views.

Setup: center coordinates at the disk center, scale so x and y lie in [-1, 1] at the limb (so r = 1 is the disk radius). The front-hemisphere height is:

z = \sqrt{1 - x^2 - y^2}, \quad x^2 + y^2 \leq 1

Rotate the sphere around the vertical (Y) axis by angle θ (positive for left eye, negative for right):

x' = x \cos\theta + z \sin\theta, \quad y' = y

Project back to pixel coordinates:

u = c_x + r \cdot x', \quad v = c_y + r \cdot y

where (cx, cy) is the disk center in the image and r is the disk radius in pixels. The result is implemented as cv2.remap with Lanczos4 interpolation; pixels outside the disk get borderValue=0. This correctly curves the sphere so that limb features move more than central features — the natural stereo effect of looking at a 3D ball from two angles.

8.2 Ring geometry (Saturn)

Rings are modeled as a tilted elliptical annulus in the image plane. For a position (x, y) relative to the disk center, rotate into the ring's own frame by -PA to get (xr, yr). The outer ellipse condition is:

\frac{x_r^2}{a_o^2} + \frac{y_r^2}{b_o^2} \leq 1

with ao = (outer factor) · r and bo = ao · tilt. The inner ellipse is the same with ai, bi. The ring annulus is:

\mathcal{A} = \mathcal{E}_{\mathrm{outer}} \wedge \neg\, \mathcal{E}_{\mathrm{inner}}

The tilt parameter (b/a) encodes the viewing inclination of the ring plane:

b = a \cdot \mathrm{tilt}, \quad \mathrm{tilt} = \cos(\mathrm{inc})

so tilt = 1 is face-on (circle) and tilt → 0 is edge-on. For true 3D geometry in the Interactive HTML export, this is inverted:

\mathrm{inc} = \arccos(\mathrm{tilt})

to recover the actual ring-plane inclination from the apparent axis ratio in your image.

8.3 Ring front/back split and occlusion

The ring plane crosses the planet body: part of the ring sits in front of the body (closer to you), part sits behind. To composite them correctly, we split the ring annulus into two halves using the signed distance along the minor-axis normal:

s = x\,n_x + y\,n_y, \quad \mathrm{front} = (s > 0)

where (nx, ny) = (cos(PA + 90°), sin(PA + 90°)) is the unit vector along the ring plane's minor axis in the image. During compositing, back-half ring pixels are drawn first (so the planet body overpaints them), then the planet body is drawn, then front-half ring pixels (so they sit on top of the body). This creates the familiar "ring passing in front of Saturn" visual effect.

8.4 Ring stereo via yaw warp

Rings are flat 2D structures — the sphere-reprojection math from §8.1 doesn't apply. Instead, we use a simpler yaw warp for stereo disparity on the ring pixels:

x' = c_x + (x - c_x) \cos\theta

which horizontally foreshortens the ring positions around the rotation center. This produces parallax that scales with distance from the center (so ring tips move more than ring bases), matching how a rotating ring plane would appear to shift between two eye positions.

8.5 Pseudo-surface heightmap and disparity warp

For the Pseudo surface planet type, image brightness is treated as 3D height. The pipeline, in order:

1. Compute luminance as the Rec.709 weighted sum: Y = 0.299·R + 0.587·G + 0.114·B.

2. Center around the median so background is near zero height:

h = \mathrm{luma} - \mathrm{median}(\mathrm{luma})

3. Apply gamma shaping (preserving sign) to control contrast:

h_\gamma = \mathrm{sign}(h) \cdot |h|^\gamma

Default γ = 1.15 emphasizes bright peaks slightly; γ < 1 broadens depth; γ > 1 sharpens it.

4. Normalize by MAD (Median Absolute Deviation) so bright stars don't dominate:

\mathrm{MAD} = \mathrm{median}(|h - \mathrm{median}(h)|)
h_{\mathrm{norm}} = \frac{h_\gamma}{6 \cdot \mathrm{MAD}}

The gain divisor 6 gives a visually comfortable amplitude without stars exploding into huge disparity spikes. The result is clipped to [-1, 1].

5. Compute per-pixel disparity from the stereo strength θ:

\Delta_{\max} = \frac{\theta}{25^\circ} \cdot 0.12 \cdot \min(H, W)
\Delta = h_{\mathrm{norm}} \cdot \Delta_{\max}

and clamp Δmax to at most 0.35 · min(H, W) so disparity never gets absurd on large frames.

6. Warp each pixel horizontally by ±½Δ for the left/right views:

x_L = x + \frac{1}{2}\Delta, \quad x_R = x - \frac{1}{2}\Delta

Bilinear remap (INTER_LINEAR, deliberately not Lanczos) because Lanczos ringing on sharp stars would produce visible halos in the output.

8.6 Anaglyph composition

The red/cyan anaglyph composite uses luminance from each eye to drive one color channel:

L_Y = 0.299\, R_L + 0.587\, G_L + 0.114\, B_L
\mathrm{Out}_R = L_Y, \quad \mathrm{Out}_G = \mathrm{Out}_B = R_Y

Luminance (rather than per-color-channel copying) is used because it's more robust across different source color balances — a stereo pair derived from a monochrome luminance capture produces the same anaglyph as one from a well-balanced RGB. The red lens of the glasses blocks the cyan (G+B) channels, delivering only the left-eye luminance to the left eye; the cyan lens blocks red, delivering only the right-eye luminance to the right eye. Your visual system fuses the two monochrome views into depth.

8.7 Galaxy top-down deprojection

The Galaxy Polar View reverses the perspective-and-tilt projection that turned the real face-on galactic disk into the elliptical patch you see in your image. Given an output grid (u, v) ∈ [-1, 1] in the deprojected disk plane:

1. Apply the inclination foreshortening (y compressed by the tilt factor):

x_e = u, \quad y_e = v \cdot \mathrm{tilt}

2. Rotate by the galaxy's position angle α (negative, to undo the on-sky rotation):

x_r = x_e \cos\alpha - y_e \sin\alpha, \quad y_r = x_e \sin\alpha + y_e \cos\alpha

3. Scale by the galaxy's apparent radius r in pixels and translate back to image coordinates:

u = c_x + r X, \quad v = c_y + r Y, \quad \text{visible}: Z \geq 0

where X and Y are the rotated-and-tilted plane coordinates. The output image is sampled by cv2.remap at these back-projected coordinates. Pixels where (u, v) falls outside the galaxy's apparent ellipse remain black.

The result: a galaxy that looked like a thin needle (edge-on) can be shown as a face-on disk, revealing spiral structure that was foreshortened out of visibility in the original frame. This is purely a geometric reprojection — it doesn't invent any new information, so features that were hidden behind the disk from your line of sight stay hidden. But features that were just squashed by projection recover their original on-disk shape.

8.8 Equirectangular texture for Interactive 3D sphere

For the Plotly sphere export, the planet disk is first converted to an equirectangular (latitude/longitude) texture that can be mapped onto a sphere mesh. For each (lat φ, lon λ) in the texture:

X = \cos\phi \sin\lambda, \quad Y = \sin\phi, \quad Z = \cos\phi \cos\lambda

Orthographically project onto the disk:

u = c_x + r X, \quad v = c_y + r Y, \quad \text{visible}: Z \geq 0

and sample the disk pixel at (u, v). Points on the back hemisphere (Z < 0) stay black because you have no information about what's behind. The resulting equirectangular image is then wrapped onto a Plotly Mesh3d sphere, giving you a rotatable 3D planet where the near-side pixels are your real data and the far side is dark.

8.9 Automatic disk detection (WinJUPOS-style)

The disk-detection pipeline (used both for automatic ROI centering and in the Auto-detect button of the adjust dialog):

  1. Percentile stretch the green channel to uint8 (1st-99.5th percentile).
  2. Gaussian blur with σ=1.2 to reduce noise.
  3. Otsu's method to find the optimal threshold between background and planet.
  4. Morphological open+close with a 7×7 ellipse kernel to clean the mask.
  5. Connected-components; pick the largest component with area ≥ 200 pixels.
  6. Centroid gives (cx, cy). Equivalent radius from area:
    r = \sqrt{\frac{A_{\mathrm{disk}}}{\pi}}
  7. For ellipse modes (Saturn, Galaxy, Planet-axis): extract the component's contour and fit an ellipse with cv2.fitEllipse, recovering the major/minor axes, orientation angle, and refined center all in one step. The ellipse PA and the b/a tilt both come out of this fit directly.

This matches the WinJUPOS approach of fitting a limb ellipse rather than assuming a perfect circle — valuable for Jupiter and Saturn, which are visibly oblate, and essential for galaxies, which are inclined.

8.10 Background parallax math

The background depth setting determines how much the background participates in stereo:

\Delta_{\mathrm{bg}} = p_{\mathrm{depth}} \cdot \Delta_{\mathrm{planet}}

where pdepth is the depth percentage from the slider (0 to 1 for 0% to 100%). The background is then shifted by ±½Δbg for the left/right views. At pdepth = 0 the shift is zero and both views see the same background — the stars appear "screen locked". At pdepth = 1 the background shifts the same as the planet — stars appear "at planet depth". The 25% default puts stars visually further than the planet, which is the natural astronomical ordering.

Credits. 3D Projection — the six-mode output system, the four planet-type pipelines, the Saturn ring geometry with front/back occlusion split, the pseudo-surface heightmap with MAD normalization, the galaxy top-down deprojection, the WinJUPOS-style auto-detect, and the Plotly Mesh3d / Scatter3d HTML exports — is original work by Franklin Marek for SetiAstro Suite Pro. Standard components credited to the community: OpenCV (cv2.remap, cv2.fitEllipse, cv2.connectedComponentsWithStats) for warping and segmentation; Otsu's method (Otsu 1979) for automatic thresholding; the orthographic sphere-to-disk projection is standard computer graphics; the red/cyan luminance anaglyph convention follows mainstream 3D-glasses practice; Plotly for the interactive 3D exports (via CDN); the equirectangular texture mapping is the standard spherical-image convention used across every 3D rendering engine.