Manual técnico · versión 1 · agosto de 2026

Technical manual · version 1 · August 2026

Fusión HDR lineal y aplanado radial de la corona solar

Linear HDR merge and radial flattening of the solar corona

eclipse_hdr.py · Python 3 · numpy, scipy, scikit-image, rawpy

↗ Código fuente · scripts/eclipse/eclipse_hdr.py ↗ Source code · scripts/eclipse/eclipse_hdr.py

El programa toma una serie de RAW en horquilla, reconstruye la radiancia lineal de la escena a lo largo de todo el rango dinámico del conjunto, registra los fotogramas ajustando una circunferencia al limbo lunar y divide la imagen por su propio perfil radial para que la estructura azimutal de la corona quede visible sin recurrir a ningún mapeo tonal perceptual.

The program takes a series of RAW files in an exposure bracket, reconstructs the linear radiance of the scene across the whole dynamic range of the set, registers the frames by fitting a circle to the lunar limb and divides the image by its own radial profile, so that the azimuthal structure of the corona becomes visible without recourse to any perceptual tone mapping.

0 -1 -2 -3 1 1,5 1.5 2 3 4 r / R de la Luna (escala logarítmica) r / R of the Moon (logarithmic scale) log₁₀ I (dex) 3,58 dex 3.58 dex 01_hdr_lineal_f32.tif 02_hdr_aplanado_f32.tif
Datos reales de la validación interna del programa: perfil radial de luminancia medido sobre sus propias salidas. La intensidad cae 3,58 dex (un factor 3800) entre 1,05 y 4,1 radios lunares; tras la división por el perfil, el residuo radial queda en 0,0018 dex de RMS. Ninguna curva de mapeo tonal comprime ese gradiente: se elimina por división.Real data from the program's internal validation: radial luminance profile measured on its own outputs. The intensity falls by 3.58 dex (a factor of 3800) between 1.05 and 4.1 lunar radii; after division by the profile, the radial residual stands at 0.0018 dex RMS. No tone mapping curve compresses that gradient: it is removed by division.
0,078 px0.078 pxerror de registroregistration error
0,0100 dex0.0100 dexRMS fotométricophotometric RMS
16 EVhorquilla validadavalidated bracket
7etapas del flujopipeline stages
1 · RAW lineal 1 · linear RAW 2 · limbo 2 · limb 3 · fusión 3 · merge 4 · registro 4 · registration 5 · fondo de cielo 5 · sky background 6 · perfil radial 6 · radial profile 7 · realce y salida 7 · enhancement and output
Pregunta directa Direct question

¿Alinea las fotos?

Does it align the frames?

Sí, por ajuste del limbo lunar Yes, by fitting the lunar limb

El registro no usa correlación de contenido ni detección de puntos de interés, que fracasan con un gradiente radial de tres órdenes de magnitud. Ajusta una circunferencia al limbo de la Luna con precisión subpíxel y traslada cada fotograma al centro del fotograma de referencia (el de exposición mediana) por interpolación con splines cúbicos. En la validación interna el error residual frente a la posición verdadera es de 0,078 px.

Lo que no hace: no corrige rotación, ni escala, ni distorsión. Solo traslación. Las consecuencias medibles de esa decisión están cuantificadas en Limitaciones, apartados L2 y L3.

Registration uses neither content correlation nor keypoint detection, both of which fail against a radial gradient of three orders of magnitude. It fits a circle to the limb of the Moon with sub-pixel precision and translates every frame onto the centre of the reference frame (the one of median exposure) by cubic spline interpolation. In the internal validation the residual error against the true position is 0.078 px.

What it does not do: it corrects neither rotation, nor scale, nor distortion. Translation only. The measurable consequences of that decision are quantified in Limitations, items L2 and L3.

El registro se puede desactivar con --no-align. Tiene dos usos legítimos: probar el flujo completo con cualquier horquilla estática antes del eclipse, y procesar tomas con seguimiento ecuatorial en las que el desplazamiento entre fotogramas es inferior a la fracción de píxel que introduciría la interpolación.

Registration can be switched off with --no-align. It has two legitimate uses: exercising the whole pipeline on any static exposure bracket ahead of the eclipse, and processing frames taken on an equatorial mount, where the displacement between frames is smaller than the fraction of a pixel that the interpolation itself would introduce.


Alcance Scope

Qué produce y qué deja fuera

What it produces and what it leaves out

El programa resuelve un problema fotométrico, no estético. Su salida principal es un mapa de radiancia relativa; la imagen presentable es un subproducto.

The program solves a photometric problem, not an aesthetic one. Its principal output is a map of relative radiance; the presentable image is a by-product.

Sí

Yes

  • Decodificado RAW estrictamente lineal, sin curva, sin brillo automático, sin recorte de altas luces.
  • Máscara de saturación medida sobre el mosaico de Bayer, antes del interpolado cromático.
  • Registro subpíxel por geometría del limbo.
  • Fusión con pesos de varianza inversa para ruido fotónico.
  • Sustracción del fondo de cielo (crepúsculo más extinción) con un modelo polinómico por canal.
  • Compresión del gradiente coronal por división del perfil radial azimutal.
  • Realce multiescala opcional, con el disco lunar protegido frente a los anillos de Gibbs.
  • Strictly linear RAW decoding: no curve, no automatic brightening, no highlight clipping.
  • Saturation mask measured on the Bayer mosaic, before demosaicing.
  • Sub-pixel registration from limb geometry.
  • Merge with inverse-variance weights for photon noise.
  • Subtraction of the sky background (twilight plus extinction) with a per-channel polynomial model.
  • Compression of the coronal gradient by division of the azimuthally averaged radial profile.
  • Optional multiscale enhancement, with the lunar disc shielded from Gibbs ringing.

No

No

  • No hace calibración con flats, darks ni mapas de píxeles calientes. Solo se resta el nivel de negro que declara el fabricante en el RAW.
  • No alinea por rotación ni corrige rotación de campo.
  • No rechaza fotogramas: una nube, un cable o una vibración entran en la media ponderada.
  • No hace deconvolución, ni corrección de aberración cromática, ni eliminación de reflejos internos.
  • No es un revelador: la gestión de color final, el equilibrio y el recorte se hacen después, en Photoshop o en Capture One, sobre el TIFF de 16 bits.
  • It performs no calibration with flat fields, darks or hot-pixel maps. Only the black level declared by the manufacturer in the RAW is subtracted.
  • It does not align for rotation, nor correct field rotation.
  • It rejects no frames: a cloud, a cable or a vibration enters the weighted mean.
  • It performs no deconvolution, no chromatic aberration correction and no removal of internal flare.
  • It is not a raw converter: the final colour management, the balance and the crop are done afterwards, in Photoshop or Capture One, on the 16-bit TIFF.

Puesta en marcha Getting started

Instalación y arranque

Installation and first run

# dependencias
pip install numpy scipy scikit-image tifffile pillow rawpy exifread
brew install exiftool        # opcional, respaldo de metadatos

# 1. validación interna con corona sintética, no necesita ficheros
python eclipse_hdr.py --selftest

# 2. ensayo con cualquier horquilla estática tuya, a media resolución
python eclipse_hdr.py bracket/*.CR3 -o prueba --no-align --half

# 3. procesado real
python eclipse_hdr.py totalidad/IMG_2*.CR3 -o salida
# dependencies
pip install numpy scipy scikit-image tifffile pillow rawpy exifread
brew install exiftool        # optional, metadata fallback

# 1. internal validation on a synthetic corona, needs no files
python eclipse_hdr.py --selftest

# 2. rehearsal on any static bracket of your own, at half resolution
python eclipse_hdr.py bracket/*.CR3 -o prueba --no-align --half

# 3. the real run
python eclipse_hdr.py totalidad/IMG_2*.CR3 -o salida

El paso 2 es el que conviene hacer antes del día 12: confirma que LibRaw decodifica el formato de tu cámara, que los tiempos de exposición se leen del EXIF y que el ordenador aguanta la memoria que exige la resolución completa. Si el EXIF no aporta ExposureTime, el programa se detiene y pide los tiempos por --times 1/8000,1/2000,... en el mismo orden que los ficheros.

Step 2 is the one worth running before the twelfth: it confirms that LibRaw decodes your camera's format, that the exposure times are read from the EXIF, and that the computer withstands the memory that full resolution demands. If the EXIF supplies no ExposureTime, the program halts and asks for the times through --times 1/8000,1/2000,... in the same order as the files.

Memoria Memory

El acumulador mantiene tres arrays float32 del tamaño del fotograma más el fotograma más corto de reserva. Para 45 Mpx en color son unos 2,2 GB, y cada fotograma cargado añade otros 0,5 GB temporales. Los fotogramas se procesan de uno en uno, en flujo, así que el consumo no crece con el número de tomas, solo con la resolución. Con menos de 8 GB libres, usa --half.

The accumulator holds three float32 arrays the size of the frame, plus the shortest frame in reserve. For 45 Mpx in colour that is some 2.2 GB, and each frame loaded adds a further 0.5 GB temporarily. Frames are processed one at a time, as a stream, so the consumption does not grow with the number of exposures, only with the resolution. With less than 8 GB free, use --half.


Algoritmos Algorithms

Las siete etapas

The seven stages

El programa recorre los ficheros dos veces. La primera pasada detecta el limbo a media resolución para obtener una estimación robusta y encadenada del centro; la segunda carga a resolución completa, refina, traslada y acumula.

The program walks through the files twice. The first pass detects the limb at half resolution in order to obtain a robust, chained estimate of the centre; the second loads at full resolution, refines, translates and accumulates.

1 · Decodificado RAW lineal

1 · Linear RAW decoding

Se llama a LibRaw a través de rawpy con gamma=(1,1), no_auto_bright=True, salida de 16 bits y primarios sRGB. El resultado es proporcional al número de fotoelectrones por píxel, con los multiplicadores del equilibrio de blancos aplicados (--wb camera o --wb daylight). La linealidad es la condición que permite dividir por el tiempo de exposición en la etapa 3.

LibRaw is called through rawpy with gamma=(1,1), no_auto_bright=True, 16-bit output and sRGB primaries. The result is proportional to the number of photoelectrons per pixel, with the white balance multipliers applied (--wb camera or --wb daylight). Linearity is the condition that permits division by the exposure time at stage 3.

La saturación no se detecta en la imagen revelada, donde el interpolado cromático ya ha mezclado píxeles buenos con píxeles a tope, sino en el mosaico:

Saturation is not detected on the developed image, where demosaicing has already blended sound pixels with pixels at full scale, but on the mosaic:

saturado ⇔ M ≥ negro + 0,97 (blanco − negro)
saturated ⇔ M ≥ black + 0.97 (white − black)

La máscara se reorienta según el flip declarado en el RAW, se combina en OR con un criterio de respaldo sobre la imagen revelada y se dilata dos iteraciones para cubrir la contaminación que el interpolado propaga a los vecinos.

The mask is reoriented according to the flip declared in the RAW, combined by OR with a fallback criterion on the developed image, and dilated by two iterations to cover the contamination that demosaicing propagates to the neighbours.

Efecto secundario útil de --half A useful side effect of --half

Con half_size=True LibRaw promedia cada celda 2×2 de Bayer en lugar de interpolar. No hay interpolado cromático, por lo que desaparecen los artefactos de laberinto y el falso color en el limbo, donde el gradiente es más violento. El precio es la mitad de resolución lineal. Para fotometría del gradiente radial suele ser un buen intercambio.

With half_size=True, LibRaw averages each 2×2 Bayer cell instead of interpolating. There is no demosaicing, so the maze artefacts and the false colour at the limb, where the gradient is at its most violent, both disappear. The price is half the linear resolution. For photometry of the radial gradient this is usually a sound bargain.

2 · Detección del limbo lunar

2 · Detection of the lunar limb

Dos fases. La inicialización usa la transformada de Hough para circunferencias sobre una versión submuestreada y comprimida en logaritmo de la luminancia, con detección de bordes de Canny (σ = 2) y un barrido de 40 radios entre 0,04 y 0,35 de la dimensión menor del fotograma. Da un centro con error de unos pocos píxeles.

Two phases. Initialisation uses the circular Hough transform on a downsampled, logarithmically compressed version of the luminance, with Canny edge detection (σ = 2) and a sweep of 40 radii between 0.04 and 0.35 of the shorter dimension of the frame. It yields a centre accurate to a few pixels.

El refinado no usa bordes binarios. Se trazan 720 rayos desde el centro provisional, se muestrea log I a lo largo de cada rayo en 129 puntos entre 0,8 y 1,2 r₀, se suaviza (σ = 2 muestras) y se localiza el máximo de la derivada radial. La posición subpíxel sale del ajuste parabólico a las tres muestras centrales:

The refinement uses no binary edges. Some 720 rays are traced from the provisional centre, log I is sampled along each ray at 129 points between 0.8 and 1.2 r₀, smoothed (σ = 2 samples), and the maximum of the radial derivative is located. The sub-pixel position follows from a parabolic fit to the three central samples:

δ = ½ (g−1 − g+1) / (g−1 − 2g0 + g+1)

Con los 720 puntos de borde se ajusta la circunferencia por el método algebraico de Kasa, que linealiza el problema escribiendo x² + y² = 2ax + 2by + c y resolviéndolo por mínimos cuadrados. El ajuste se repite con recorte a 2,5σ del residuo radial, y el ciclo completo (rayos, bordes, ajuste) se itera tres veces. Se descartan los rayos cuyo gradiente máximo no llega al 30 % de la mediana, que es lo que ocurre en el borde del encuadre o sobre una protuberancia muy brillante.

The 720 edge points are then fitted with a circle by Kåsa's algebraic method, which linearises the problem by writing x² + y² = 2ax + 2by + c and solving it by least squares. The fit is repeated with 2.5σ sigma clipping of the radial residual, and the whole cycle (rays, edges, fit) is iterated three times. Rays whose maximum gradient falls short of 30 % of the median are discarded, which is what happens at the edge of the frame or over a very bright prominence.

La función devuelve centro, radio, desviación típica del residuo en píxeles y número de puntos supervivientes. Esos dos últimos valores son el control de calidad que aparece en el registro de ejecución.

The function returns centre, radius, standard deviation of the residual in pixels and number of surviving points. Those last two values are the quality control that appears in the execution log.

3 · Fusión HDR

3 · Linear HDR merge

La exposición relativa de cada toma se calcula desde el EXIF como

The relative exposure of each frame is computed from the EXIF as

e = t · ISO / N², normalizada a max(e) = 1
e = t · ISO / N², normalised to max(e) = 1

y la radiancia se estima como media ponderada de las estimaciones individuales:

and the radiance is estimated as a weighted mean of the individual estimates:

L = Σi wi Ii / ei ⁄ Σi wi

El peso tiene tres factores. Uno anula los píxeles saturados con una rampa suave entre 0,92 y 0,98 de la escala, más la máscara del mosaico. Otro anula los que están bajo el suelo de ruido, con rampa entre --floor y tres veces ese valor. El tercero es ei, y no es arbitrario: si el ruido dominante es fotónico, var(I) ∝ I, de modo que la varianza del estimador L̂i = Ii/ei es proporcional a L/ei. El peso de varianza inversa es entonces proporcional a la exposición, exactamente lo que se aplica.

The weight has three factors. One annuls the saturated pixels with a smooth ramp between 0.92 and 0.98 of full scale, together with the mosaic mask. Another annuls those below the noise floor, with a ramp between --floor and three times that value. The third is ei, and it is not arbitrary: if the dominant noise is photon noise, var(I) ∝ I, so that the variance of the estimator L̂i = Ii/ei is proportional to L/ei. The inverse-variance weight is then proportional to the exposure, which is exactly what is applied.

Los píxeles en los que ningún fotograma aporta peso (el núcleo saturado en todas las tomas) se rellenan con la estimación de la exposición más corta, para que la imagen no contenga huecos. Es un relleno, no una medida: en esa zona la fotometría no existe.

Pixels to which no frame contributes any weight (the core, saturated in every exposure) are filled in with the estimate from the shortest exposure, so that the image contains no holes. It is a fill, not a measurement: in that region there is no photometry.

Cuando hay varias tomas por escalón de exposición, y con ráfagas las hay, los fotogramas de igual exposición (tolerancia de 0,25 EV, con independencia del orden de captura) se combinan antes con una media recortada por píxel: con n ≥ 3 se descarta el máximo, con n ≥ 8 también el mínimo. Un avión, un satélite o una vibración afectan a un solo fotograma del grupo, y el recorte los elimina con un coste en SNR de (n−2)/n. El peso del grupo en la fusión es proporcional a e · nef. Se controla con --trim.

When there are several exposures per bracket step, as there are when shooting in bursts, the frames of equal exposure (tolerance of 0.25 EV, irrespective of the order of capture) are first combined by a per-pixel trimmed mean: with n ≥ 3 the maximum is discarded, with n ≥ 8 the minimum as well. An aircraft, a satellite or a vibration affects a single frame of the group, and this outlier rejection removes them at a cost in SNR of (n−2)/n. The weight of the group in the merge is proportional to e · nef. It is governed by --trim.

4 · Registro

4 · Registration

La referencia es el fotograma de exposición mediana, elegido porque es el que tiene a la vez limbo bien definido y corona con señal suficiente. Para cada uno de los demás se aplica

The reference is the frame of median exposure, chosen because it is the one that has at once a well-defined limb and a corona with sufficient signal. To each of the others is applied

(Δx, Δy) = (xref − xi, yref − yi)

con scipy.ndimage.shift de orden 3 sobre cada canal, y de orden 1 con umbral 0,2 sobre la máscara de saturación, para que la máscara siga cubriendo lo que debe cubrir después del desplazamiento. Los desplazamientos por debajo de 0,05 px se omiten, para no interpolar sin necesidad.

with scipy.ndimage.shift of order 3 on each channel, and of order 1 with a threshold of 0.2 on the saturation mask, so that the mask still covers what it must cover after the displacement. Shifts below 0.05 px are skipped, so as not to interpolate needlessly.

La cadena de inicialización importa: en la primera pasada el centro detectado en un fotograma sirve de estimación inicial para el siguiente. Sin seguimiento, a 400 mm el arrastre sidéreo es de unos 6,5 px/s, así que en una ráfaga de nueve tomas el limbo se desplaza decenas de píxeles y la búsqueda ciega por Hough se vuelve frágil.

The chain of initialisation matters: in the first pass the centre detected in one frame serves as the initial estimate for the next. Without tracking, at 400 mm the sidereal trailing amounts to some 6.5 px/s, so that across a burst of nine exposures the limb travels tens of pixels and the blind Hough search turns fragile.

5 · Fondo de cielo

5 · Sky background

Se ajusta por canal un polinomio (constante, plano o cuadrática completa) a los píxeles con r > k · RLuna, con k = 4 por omisión. El muestreo es en rejilla de paso ≈ min(H,W)/700 y con un margen que excluye el borde afectado por los desplazamientos del registro.

A polynomial (constant, plane or full quadratic) is fitted per channel to the pixels with r > k · RMoon, with k = 4 by default. Sampling is on a grid of step ≈ min(H,W)/700, with a margin that excludes the border affected by the registration shifts.

El recorte de valores atípicos es deliberadamente asimétrico: se conservan los residuos entre −4σ y +2σ. La contaminación que hay que rechazar es corona residual y estrellas, es decir, siempre positiva, mientras que las fluctuaciones negativas son ruido legítimo del fondo. Un recorte simétrico sesgaría el fondo hacia arriba y se comería la corona externa. Antes de iterar se descarta además todo lo que supera el percentil 60.

The outlier rejection is deliberately asymmetric: residuals between −4σ and +2σ are retained. The contamination that must be rejected is residual corona and stars, that is to say always positive, whereas the negative fluctuations are legitimate background noise. A symmetric sigma clipping would bias the background upwards and eat into the outer corona. Before iterating, everything above the 60th percentile is additionally discarded.

Si la fracción de cielo disponible baja del 4 % del encuadre, el modelo polinómico está mal condicionado y el programa degrada solo a fondo constante, avisando en el registro.

If the fraction of available sky falls below 4 % of the frame, the polynomial model is ill-conditioned and the program degrades on its own to a constant background, giving notice in the log.

Por qué un plano basta Why a plane suffices

Con el Sol a 12° de altura, la masa de aire es ≈ 4,8 y la extinción atmosférica varía de forma monótona con la altura aparente. En un encuadre de 3,4° de alto a 400 mm, el gradiente vertical de transmisión es del orden del 15 %, suave y casi lineal a esa escala. --bg poly2 tiene sentido si hay bruma estructurada o luz parásita del cielo crepuscular cerca del horizonte.

With the Sun at 12° of altitude, the airmass is ≈ 4.8 and atmospheric extinction varies monotonically with apparent altitude. Across a frame 3.4° tall at 400 mm, the vertical gradient of transmission is of the order of 15 %, gentle and very nearly linear at that scale. --bg poly2 makes sense if there is structured haze or stray light from the twilit sky near the horizon.

6 · Aplanado radial

6 · Radial flattening

Es la etapa que sustituye al mapeo tonal. Se construye el perfil radial en anillos de 1 px con media recortada a 3σ, calculada con bincount para que el coste sea lineal. Solo entran píxeles con r ≥ RLuna + 3, de modo que el disco lunar no contamine los primeros anillos. Dentro del disco el divisor se congela en su valor en RLuna + 4, y después se suaviza el perfil en logaritmo con σ = 3 anillos. La imagen aplanada es

This is the stage that stands in for tone mapping. The radial profile is built in 1 px annuli with a 3σ trimmed mean, computed with bincount so that the cost stays linear. Only pixels with r ≥ RMoon + 3 are admitted, so that the lunar disc does not contaminate the innermost annuli. Within the disc the divisor is frozen at its value at RMoon + 4, and the profile is then smoothed in the logarithm with σ = 3 annuli. The flattened image is

F(x) = L(x) / p(r(x))

seguido de una normalización por la mediana en el anillo 1,05 a 1,4 RLuna, para que F ≈ 1 justo fuera del limbo. Con --profile lum los tres canales se dividen por el mismo perfil de luminancia, lo que conserva los cocientes de color y por tanto la información cromática de la corona. Con --profile rgb cada canal se divide por el suyo, lo que neutraliza cualquier gradiente radial de color, incluida la extinción diferencial que el modelo de fondo no haya capturado, a cambio de destruir el color real.

followed by a normalisation to the median within the annulus 1.05 to 1.4 RMoon, so that F ≈ 1 just outside the limb. With --profile lum the three channels are divided by the same luminance profile, which preserves the colour ratios and hence the chromatic information of the corona. With --profile rgb each channel is divided by its own, which neutralises any radial colour gradient, including the differential extinction that the background model has failed to capture, at the cost of destroying the real colour.

Conceptualmente esto es un filtro de paso alto circular, la versión de simetría exacta del filtro adaptativo que Druckmüller aplica a sus composiciones. La ventaja frente a un desenfoque gaussiano restado es que no introduce halos alrededor del limbo, porque el divisor no conoce nada más que el radio.

Conceptually this is a circular high-pass filter, the exactly symmetric counterpart of the adaptive filter that Druckmüller applies to his composites. Its advantage over a subtracted Gaussian blur is that it introduces no haloes around the limb, because the divisor knows nothing whatever beyond the radius.

Consecuencia inevitable An unavoidable consequence

Dividir por el perfil radial elimina, por construcción, toda la estructura radial real: la caída de brillo de un penacho a lo largo de su eje desaparece junto con el gradiente coronal. La imagen aplanada revela estructura azimutal y no es fotométrica. Cualquier medida se hace sobre 01_hdr_lineal_f32.tif.

Dividing by the radial profile removes, by construction, all the real radial structure: the fall in brightness of a coronal streamer along its axis vanishes together with the coronal gradient. The flattened image reveals azimuthal structure and is not photometric. Any measurement is made on 01_hdr_lineal_f32.tif.

7 · Realce multiescala y codificación de salida

7 · Multiscale enhancement and output encoding

Antes de filtrar, F se recorta a un intervalo derivado de los percentiles 0,2 y 99,8 dentro del anillo estructural (1,05 a 3,5 RLuna), porque el ruido del campo exterior queda amplificado por la división y de lo contrario domina los filtros gaussianos. El disco lunar se rellena con la mediana de un anillo estrecho justo por fuera del limbo, únicamente para el cálculo de los desenfoques, y el resultado se recompone con un degradado de 3 px. Ambas cosas evitan el anillo oscuro que aparecería en el limbo.

Before filtering, F is clipped to an interval derived from the 0.2 and 99.8 percentiles within the structural annulus (1.05 to 3.5 RMoon), because the noise of the outer field is amplified by the division and would otherwise dominate the Gaussian filters. The lunar disc is filled with the median of a narrow annulus just outside the limb, solely for the computation of the blurs, and the result is recomposed with a 3 px feather. Both measures avoid the dark ring that would otherwise appear at the limb.

E = G + Σk gk (G − G ∗ N(0, σk))

Las escalas por omisión, σ = 3, 10, 30 y 90 px con ganancias decrecientes, cubren desde las estrías finas de la corona hasta los penachos. La codificación final estira entre los percentiles 0,5 y 99,7 medidos también en el anillo estructural, y aplica gamma 2,2. El estirado se mide donde está la señal que interesa, no en todo el fotograma, que es el error que produce imágenes lavadas.

The default scales, σ = 3, 10, 30 and 90 px with decreasing gains, span everything from the fine striations of the corona to the coronal streamers. The final encoding stretches between the 0.5 and 99.7 percentiles, likewise measured within the structural annulus, and applies gamma 2.2. The stretch is measured where the signal of interest lies, not across the whole frame, which is the error that yields washed-out images.


Referencia Reference

Opciones de la línea de órdenes

Command-line options

Todas las opciones y su valor por omisiónEvery option and its default value
OpciónOption OmisiónDefault Cuándo tocarlaWhen to touch it
ficheros-Patrones admitidos, *.CR3. Se ordenan y se eliminan duplicados. Mínimo dos.Glob patterns accepted, *.CR3. They are sorted and de-duplicated. Two files minimum.
-o, --outsalidaDirectorio de salida, se crea si no existe.Output directory; it is created if it does not exist.
--selftest-Validación con corona sintética. Ejecutar siempre tras instalar.Validation on a synthetic corona. Always run it after installing.
--half-Media resolución sin interpolado cromático. Pruebas, equipos con poca memoria, o cuando prima la limpieza del limbo.Half resolution without demosaicing. Trials, machines short of memory, or wherever cleanliness at the limb comes first.
--wbcameradaylight da un punto de partida colorimétrico reproducible, independiente del ajuste de la cámara.daylight gives a reproducible colorimetric point of departure, independent of the camera setting.
--times-Solo si falta ExposureTime en el EXIF. Acepta 1/2000 o 0.0005.Only if ExposureTime is missing from the EXIF. Accepts 1/2000 or 0.0005.
--moon-radiusautoRadio lunar aproximado en píxeles a resolución completa. Restringe el barrido de Hough si la detección falla.Approximate lunar radius in pixels at full resolution. Restricts the Hough sweep if detection fails.
--centerautoCentro manual x,y, útil con --no-align si el limbo no se detecta.Manual centre x,y, useful with --no-align if the limb is not detected.
--no-align-Sin registro. Seguimiento ecuatorial, o ensayo del flujo con material que no sea del eclipse.No registration. Equatorial tracking, or a rehearsal of the pipeline on material other than the eclipse.
--floor1.5e-3Suelo de ruido en fracción de saturación. Súbelo si el ISO es alto y aparece grano estructurado en la corona externa.Noise floor as a fraction of saturation. Raise it if the ISO is high and structured grain appears in the outer corona.
--trimautoRecorte de extremos por píxel dentro de cada grupo de igual exposición. off lo desactiva; solo tiene sentido con menos de 3 tomas por escalón.Per-pixel outlier rejection within each group of equal exposure. off disables it; that is sensible only with fewer than 3 frames per step.
--bgplanepoly2 con bruma estructurada, const con poco cielo en el encuadre, none para no tocar el fondo.poly2 with structured haze, const with little sky in the frame, none to leave the background untouched.
--bg-k4.0Radio interior de la zona de cielo, en radios lunares. Bájalo a 3 con focales largas, súbelo si sospechas corona detectable más allá de 4 R.Inner radius of the sky region, in lunar radii. Lower it to 3 at long focal lengths, raise it if you suspect detectable corona beyond 4 R.
--profilelumrgb si queda gradiente de color radial tras el fondo, aceptando que el color deja de ser real.rgb if a radial colour gradient survives the background subtraction, accepting that the colour ceases to be real.
--no-enhance-Omite el realce multiescala. Recomendable si vas a hacer el realce tú en Photoshop sobre el fichero 02.Skips the multiscale enhancement. Advisable if you intend to do the enhancement yourself in Photoshop on file 02.
--sigmas3,10,30,90Escalas del realce en píxeles. Escálalas con la resolución y la focal.Enhancement scales in pixels. Scale them with the resolution and the focal length.
--gains1.0,0.8,0.6,0.4Ganancias por escala. Por encima de 1,5 en la escala fina aparece grano.Gains per scale. Above 1.5 on the fine scale, grain appears.

Salidas Outputs

Los cinco ficheros y qué hacer con ellos

The five files and what to do with them

Contenido del directorio de salidaContents of the output directory
FicheroFile TipoType Contenido y usoContent and use
01_hdr_lineal_f32.tiffloat32 RGB Radiancia relativa, lineal, tras la fusión. Unidades arbitrarias fijadas por la exposición más larga de la serie. Los valores superan 1 hasta un factor 216. Es el único fichero fotométrico: cualquier medida, cualquier composición propia y cualquier aplanado alternativo parten de aquí.Relative radiance, linear, after the merge. Arbitrary units set by the longest exposure of the series. Values exceed 1 by up to a factor of 216. It is the only photometric file: any measurement, any composite of your own and any alternative flattening start from here.
02_hdr_aplanado_f32.tiffloat32 RGB Fondo de cielo restado y perfil radial dividido, normalizado a 1 justo fuera del limbo. Estructura azimutal visible, fotometría destruida. Es el punto de entrada natural si prefieres hacer el realce y el estirado a mano en Photoshop en modo 32 bits.Sky background subtracted and radial profile divided out, normalised to 1 just outside the limb. Azimuthal structure visible, photometry destroyed. It is the natural point of entry if you prefer to do the enhancement and the stretch by hand in Photoshop in 32-bit mode.
03_final_16bit.tifuint16 RGB Con realce multiescala, estirado por percentiles y gamma 2,2. Imagen presentable, para acabar de ajustar color y contraste local.With multiscale enhancement, percentile stretch and gamma 2.2. The presentable image, for the final adjustment of colour and local contrast.
perfil_radial.csvtextotext Columnas r_px y el perfil usado como divisor (una columna con --profile lum, tres con rgb). Sirve para reproducir el aplanado en otro programa y para comprobar que el perfil decrece de forma monótona desde el limbo.Columns r_px and the profile used as divisor (one column with --profile lum, three with rgb). It serves to reproduce the flattening in another program and to check that the profile decreases monotonically outwards from the limb.
preview.jpgjpeg Submuestreado a 2000 px de lado mayor. Control rápido, nada más.Downsampled to 2000 px on the longer side. A quick check, nothing more.
Photoshop

Los TIFF float32 se abren en modo 32 bits por canal. Al convertir a 16 bits, Photoshop ofrece un mapeo tonal: hay que elegir exposición y gamma, no ninguno de los métodos adaptativos, porque el gradiente radial ya está eliminado y cualquier compresión local volvería a introducir halos en el limbo.

The float32 TIFFs open in 32-bit-per-channel mode. On converting to 16 bits, Photoshop offers a tone mapping: choose exposure and gamma, and none of the adaptive methods, because the radial gradient has already been removed and any local compression would reintroduce haloes at the limb.


Validación Validation

Qué comprueba --selftest y qué no demuestra

What --selftest checks and what it does not prove

Se genera una escena sintética con nueve escalones de exposición separados 2 EV, 16 EV en total, y tres tomas por escalón, 27 fotogramas: corona con caída exponencial y modulación azimutal cos(5θ) que gira con el radio, disco lunar oscuro, fondo de cielo con gradiente horizontal, ruido gaussiano más ruido fotónico, saturación del núcleo en las tomas largas, deriva del centro de 4,7 px por fotograma con perturbación aleatoria y una traza brillante de satélite inyectada en un único fotograma.

A synthetic scene is generated with nine exposure steps 2 EV apart, 16 EV in all, and three frames per step, 27 frames: a corona with exponential fall-off and a cos(5θ) azimuthal modulation that rotates with radius, a dark lunar disc, a sky background with a horizontal gradient, Gaussian noise plus photon noise, saturation of the core in the long exposures, a drift of the centre of 4.7 px per frame with a random perturbation, and a bright satellite trail injected into a single frame.

El programa procesa esa serie sin conocer la verdad y se comparan cuatro cosas:

The program processes that series without knowledge of the ground truth, and four things are compared:

error de centro < 0,6 px
Obtenido: 0,078 px como máximo sobre los 27 fotogramas.
RMS fotométrico < 0,04 dex
Obtenido: 0,0100 dex en el anillo de 1,05 a 3,0 RLuna, es decir, la radiancia se reconstruye con un error del 2 % a lo largo de tres décadas.
residuo sobre la traza del transitorio < 0,05 dex
Obtenido: 0,0047 dex con el recorte activo. El control negativo, con --trim off, deja 0,0422 dex: un sesgo local del 10 % causado por un solo fotograma de 27.
radio detectado a menos de 2 px del verdadero
Obtenido: 138,13 px frente a 140 de referencia. El sesgo hacia dentro es sistemático y esperable, ver L5.
centre error < 0.6 px
Obtained: 0.078 px at most across the 27 frames.
photometric RMS < 0.04 dex
Obtained: 0.0100 dex in the annulus from 1.05 to 3.0 RMoon; that is, the radiance is reconstructed to within 2 % across three decades.
residual over the trail of the transient < 0.05 dex
Obtained: 0.0047 dex with outlier rejection active. The negative control, with --trim off, leaves 0.0422 dex: a local bias of 10 % caused by a single frame out of 27.
radius detected to within 2 px of the true value
Obtained: 138.13 px against a reference of 140. The inward bias is systematic and to be expected; see L5.

Lo que la prueba no demuestra: que LibRaw lea correctamente tu cámara, que el EXIF de tus ficheros esté completo, que la corona real, que no es axisimétrica ni exponencial, se comporte como el modelo, ni que la atmósfera colabore. Es una verificación de la implementación matemática, no del sistema completo. Para eso está el ensayo con material propio y --no-align.

What the test does not prove: that LibRaw reads your camera correctly, that the EXIF of your files is complete, that the real corona, which is neither axisymmetric nor exponential, behaves like the model, or that the atmosphere will oblige. It is a verification of the mathematical implementation, not of the complete system. For that there is the rehearsal on material of your own with --no-align.


Limitaciones Limitations

Fuentes de error, cuantificadas

Sources of error, quantified

Las cifras siguientes suponen 400 mm de focal, sensor de fotograma completo con píxel de 4,3 µm (escala de 2,22 segundos de arco por píxel) y las condiciones de la totalidad en A Coruña el 12 de agosto de 2026: 76 s de duración, Sol a 12° de altura.

The figures below assume a focal length of 400 mm, a full-frame sensor with a 4.3 µm pixel (a plate scale of 2.22 arcseconds per pixel) and the conditions of totality at A Coruña on 12 August 2026: 76 s of duration, the Sun at 12° of altitude.

L1 · La imagen aplanada no es fotométrica

L1 · The flattened image is not photometric

Ya está dicho en la etapa 6, pero es el malentendido más costoso. Dividir por p(r) elimina toda la información radial. Ninguna medida de brillo coronal, de gradiente ni de color absoluto puede hacerse sobre los ficheros 02 o 03.

This is already said at stage 6, but it is the costliest misunderstanding. Dividing by p(r) removes all the radial information. No measurement of coronal brightness, of gradient or of absolute colour can be made on files 02 or 03.

L2 · Movimiento relativo de la Luna respecto al Sol

L2 · Relative motion of the Moon with respect to the Sun

El registro fija la Luna, así que la corona se mueve. El desplazamiento relativo acumulado durante toda la totalidad es del orden de la diferencia de diámetros aparentes, aproximadamente 1 minuto de arco, es decir, unos 27 px. Mezclar fotogramas del segundo contacto con fotogramas del tercero difumina la corona en esa cantidad. Dentro de una ráfaga de 5 s el efecto baja a 1,8 px. La conclusión práctica: procesar por grupos temporales próximos y componer después, no fusionar los 76 s en un solo pase.

Registration fixes the Moon, so the corona moves. The relative displacement accumulated over the whole of totality is of the order of the difference in apparent diameters, approximately 1 arcminute, that is to say some 27 px. Mixing frames from second contact with frames from third smears the corona by that amount. Within a 5 s burst the effect falls to 1.8 px. The practical conclusion: process by groups close together in time and composite afterwards, rather than merging the whole 76 s in a single pass.

L3 · Rotación de campo sin montura ecuatorial

L3 · Field rotation without an equatorial mount

Con la cámara fija, la velocidad de rotación del campo es

With the camera fixed, the rate of field rotation is

ω ≈ 15,04 · cos φ · cos A / cos h  [°/h]
ω ≈ 15.04 · cos φ · cos A / cos h  [°/h]

con A el azimut medido desde el norte. Para φ = 43,4°, h = 12° y A ≈ 295°, sale ω ≈ 4,7 °/h, o 0,10° a lo largo de los 76 s. A 3 RLuna del centro (0,78°) eso equivale a un arrastre tangencial de 4,9 segundos de arco, unos 2,2 px, que el registro por traslación no corrige. En 5 s son 0,14 px, despreciable. De nuevo, agrupar por tiempo resuelve el problema.

with A the azimuth measured from north. For φ = 43.4°, h = 12° and A ≈ 295°, this gives ω ≈ 4.7 °/h, or 0.10° over the 76 s. At 3 RMoon from the centre (0.78°) that amounts to a tangential trailing of 4.9 arcseconds, some 2.2 px, which translation-only registration does not correct. Over 5 s it is 0.14 px, negligible. Once again, grouping by time settles the matter.

L4 · Interacción entre viñeteado y aplanado radial

L4 · Interaction between vignetting and radial flattening

El perfil radial está centrado en la Luna; el viñeteado del objetivo está centrado en el eje óptico. Si la Luna está descentrada en el encuadre, el aplanado no elimina el viñeteado y además lo convierte en una modulación azimutal espuria, indistinguible de una asimetría real de la corona. Dos remedios: encuadrar la Luna en el centro, o corregir el viñeteado antes con un flat del objetivo a esa misma abertura.

The radial profile is centred on the Moon; the vignetting of the lens is centred on the optical axis. If the Moon sits off-centre in the frame, the flattening does not remove the vignetting and moreover converts it into a spurious azimuthal modulation, indistinguishable from a real asymmetry of the corona. Two remedies: frame the Moon at the centre, or correct the vignetting beforehand with a flat field of the lens at that same aperture.

L5 · Sesgo del radio medido

L5 · Bias of the measured radius

El estimador localiza el máximo del gradiente de log I, que con una PSF finita cae dentro del borde geométrico. En la validación el radio sale 1,9 px corto sobre 140. Para el registro es inocuo, porque el sesgo es idéntico en todos los fotogramas y solo importa la diferencia de centros. Sí desplaza en torno al 1 % los umbrales que dependen de RLuna: el suelo del divisor, el anillo de normalización y la zona de cielo.

The estimator locates the maximum of the gradient of log I, which with a finite point spread function falls inside the geometric edge. In the validation the radius comes out 1.9 px short of 140. For registration this is harmless, since the bias is identical in every frame and only the difference of centres matters. It does shift by about 1 % the thresholds that depend on RMoon: the floor of the divisor, the normalisation annulus and the sky region.

L6 · Píxeles calientes y ausencia de calibración

L6 · Hot pixels and the absence of calibration

No hay resta de dark ni mapa de defectos. Un píxel caliente sobrevive a la media ponderada y aparece como un punto fijo en la corona, que el realce multiescala amplifica. Con exposiciones de medio segundo y temperatura de agosto el efecto es pequeño pero visible en las zonas más débiles. Mitigación: desactivar la reducción de ruido de larga exposición en cámara para no perder tiempo entre tomas, y restar externamente un dark del mismo tiempo e ISO si aparece.

There is no dark subtraction and no defect map. A hot pixel survives the weighted mean and shows up as a fixed point in the corona, which the multiscale enhancement amplifies. With half-second exposures and August temperatures the effect is small but visible in the faintest regions. Mitigation: switch off in-camera long-exposure noise reduction so as not to lose time between frames, and subtract a dark of the same time and ISO externally should one appear.

L7 · Umbral de saturación y equilibrio de blancos

L7 · Saturation threshold and white balance

El criterio de respaldo marca como saturado todo píxel cuyo canal máximo supera 0,96 en la imagen ya balanceada. Los multiplicadores del equilibrio de blancos son mayores que 1 en rojo y azul, así que un píxel brillante pero no saturado en el sensor puede cruzar ese umbral y quedar excluido. La consecuencia es que la corona interior puede perder la aportación de las tomas más cortas. Prevención: incluir en la horquilla una exposición claramente más corta de lo necesario, para que siempre exista un fotograma sin saturar en el limbo.

The fallback criterion marks as saturated every pixel whose maximum channel exceeds 0.96 in the already balanced image. The white balance multipliers are greater than 1 in red and blue, so a pixel that is bright but not saturated at the sensor may cross that threshold and be excluded. The consequence is that the inner corona may lose the contribution of the shortest exposures. Prevention: include in the bracket an exposure distinctly shorter than necessary, so that there is always a frame free of clipping at the limb.

L8 · Modelo de fondo de primer orden

L8 · First-order background model

Un plano no describe luz parásita interna, reflejos entre lentes ni un banco de bruma localizado. Si el residuo tras la sustracción tiene estructura, se propagará al aplanado como asimetría azimutal. Se detecta comparando el resultado con --bg plane y --bg poly2: lo que cambie de sitio no es corona.

A plane describes neither internal stray light, nor reflections between elements, nor a localised bank of haze. If the residual after subtraction has structure, it will propagate into the flattening as azimuthal asymmetry. It is detected by comparing the result with --bg plane and with --bg poly2: whatever moves is not corona.

L9 · Requisitos geométricos

L9 · Geometric requirements

El limbo completo debe estar dentro del encuadre, con al menos 90 de los 720 rayos íntegramente contenidos, y el radio ha de caer entre 0,04 y 0,35 de la dimensión menor. A 1200 mm sobre fotograma completo el disco lunar ocupa ya 1260 px de radio, más de 0,35 de la altura, y la detección automática falla: hay que dar --moon-radius.

The complete limb must lie within the frame, with at least 90 of the 720 rays wholly contained, and the radius must fall between 0.04 and 0.35 of the shorter dimension. At 1200 mm on full frame the lunar disc already spans a radius of 1260 px, more than 0.35 of the height, and automatic detection fails: --moon-radius must be supplied.

L10 · Rechazo limitado a eventos de un solo fotograma

L10 · Rejection limited to single-frame events

El recorte por grupos elimina lo que afecta a una única toma de un grupo de 3 o más. Una nube que cubre varias tomas consecutivas, un desenfoque sostenido o un píxel caliente, que por ser idéntico en todos los fotogramas del grupo sobrevive a cualquier estadístico de orden, pasan el filtro. La inspección previa sigue siendo necesaria.

Outlier rejection by group removes whatever affects a single frame of a group of 3 or more. A cloud covering several consecutive frames, a sustained defocus, or a hot pixel, which by being identical in every frame of the group survives any order statistic, all pass the filter. Prior inspection remains necessary.


Campo Field

Cómo disparar para que este flujo funcione

How to shoot so that this pipeline works

  1. Abertura e ISO fijos durante toda la totalidad. La escala fotométrica se reconstruye con t·ISO/N², pero cambiar de abertura cambia también el viñeteado y la PSF, y eso no se compensa con un número.
  2. Horquilla de 16 EV en pasos de 2 EV, por ejemplo de 1/4000 a 1/2 s a f/8 e ISO 200. Nueve tomas. El paso de 2 EV es suficiente porque la ponderación por ei hace que los solapes contribuyan de forma óptima.
  3. Ráfagas repetidas de la misma escalera. Las tomas de igual exposición se promedian con el mismo peso y la relación señal a ruido crece como √N. Con la escalera anterior cabe una decena de repeticiones en 76 s.
  4. Agrupar por tiempo al procesar. Por L2 y L3, cada grupo debería cubrir menos de unos 10 s. Se procesa cada grupo por separado y se combinan los resultados al final, con la Luna alineada y aceptando el difuminado residual de la corona, o alineando por la corona si lo que interesa es su estructura.
  5. Dejar cielo en el encuadre. A 400 mm el campo es de 5,15° × 3,44° y el radio lunar mide 420 px, de modo que la región con r > 4 R cubre el 81 % del fotograma: el plano de fondo queda bien determinado. A 800 mm esa fracción cae al 25 %, todavía por encima del mínimo, pero conviene --bg-k 3. A focales mayores, --bg const.
  6. Enfoque manual fijado antes de la totalidad, sobre el limbo lunar con ampliación en pantalla, y bloqueado. El autofoco no tiene nada a lo que agarrarse y un cambio de enfoque entre fotogramas rompe la fusión.
  7. RAW sin compresión con pérdida y sin reducción de ruido en cámara.
  1. Fixed aperture and ISO throughout totality. The photometric scale is reconstructed with t·ISO/N², but changing the aperture also changes the vignetting and the point spread function, and that is not compensated by a single number.
  2. A 16 EV bracket in 2 EV steps, for instance from 1/4000 to 1/2 s at f/8 and ISO 200. Nine frames. The 2 EV step suffices because the weighting by ei makes the overlaps contribute optimally.
  3. Repeated bursts of the same ladder. Frames of equal exposure are averaged with the same weight and the signal-to-noise ratio grows as √N. With the ladder above, a dozen or so repetitions fit within 76 s.
  4. Group by time when processing. By L2 and L3, each group should span less than about 10 s. Each group is processed separately and the results combined at the end, with the Moon aligned and the residual smearing of the corona accepted, or else aligned on the corona if it is its structure that matters.
  5. Leave sky in the frame. At 400 mm the field is 5.15° × 3.44° and the lunar radius measures 420 px, so that the region with r > 4 R covers 81 % of the frame: the background plane is well determined. At 800 mm that fraction falls to 25 %, still above the minimum, but --bg-k 3 is advisable. At longer focal lengths, --bg const.
  6. Manual focus set before totality, on the lunar limb with magnification on screen, and locked. Autofocus has nothing to seize upon, and a change of focus between frames breaks the merge.
  7. RAW without lossy compression and with in-camera noise reduction off.
Antes del día 12 Before the twelfth

Ejecuta --selftest y después una horquilla propia con --no-align --half. Lo que falla el día del eclipse no son los algoritmos, es un formato RAW que LibRaw no reconoce, un EXIF incompleto o una tarjeta llena.

Run --selftest, and then a bracket of your own with --no-align --half. What fails on the day of the eclipse is not the algorithms; it is a RAW format that LibRaw does not recognise, an incomplete EXIF or a full card.


Diagnóstico Diagnostics

Leer el registro de ejecución

Reading the execution log

rango dinamico del bracket: 16.0 EV
pase A: deteccion del limbo a media resolucion...
  IMG_4471.CR3   centro=(2612.4, 1740.8) r=210.3  sigma=0.31 px  n=698
pase B: fusion (referencia: IMG_4475.CR3)...
  IMG_4471.CR3   desplazamiento=(+27.44, -19.02) px  sigma=0.29
sigma
Desviación típica del residuo radial del ajuste de circunferencia. Por debajo de 0,5 px el limbo está bien determinado. Por encima de 1,5 px sospecha desenfoque, movimiento durante la exposición o que el ajuste ha enganchado la cromosfera en lugar del limbo.
n
Rayos supervivientes de 720. Menos de 300 indica que buena parte del limbo está fuera del encuadre o tapada por una protuberancia muy brillante.
desplazamiento
Debe crecer de forma monótona y aproximadamente lineal con el tiempo si no hay seguimiento. Un salto no monótono señala una detección errónea en ese fotograma.
rango dinámico
Si sale muy por debajo de lo que disparaste, los metadatos están mal leídos y toda la fotometría posterior es falsa. Compruébalo antes de mirar la imagen.
sigma
Standard deviation of the radial residual of the circle fit. Below 0.5 px the limb is well determined. Above 1.5 px, suspect defocus, movement during the exposure, or that the fit has latched onto the chromosphere instead of the limb. (The log is written in Spanish, without accents.)
n
Rays surviving out of 720. Fewer than 300 indicates that a good part of the limb lies outside the frame or is obscured by a very bright prominence.
desplazamiento
The displacement should grow monotonically and roughly linearly with time when there is no tracking. A non-monotonic jump signals a faulty detection in that frame.
rango dinamico
If the dynamic range comes out far below what you shot, the metadata have been misread and all the subsequent photometry is false. Check this before looking at the image.

Después, dos comprobaciones sobre las salidas. En perfil_radial.csv el perfil debe decrecer de forma monótona desde el limbo hacia fuera: un perfil no monótono significa que el centro está mal o que el fondo quedó sobrerrestado. En preview.jpg el disco lunar debe aparecer oscuro y la corona con estructura: un disco claro indica fondo sobrerrestado y valores negativos amplificados por la división.

Then two checks on the outputs. In perfil_radial.csv the profile must decrease monotonically outwards from the limb: a non-monotonic profile means either that the centre is wrong or that the background was over-subtracted. In preview.jpg the lunar disc must appear dark and the corona structured: a bright disc indicates an over-subtracted background and negative values amplified by the division.