Ce projet contient eclipse_align.py, un script Python qui recentre une sequence d'images FITS d'eclipse solaire.
Le but est de corriger la derive lente du Soleil dans le champ, sans chercher a redetecter le centre solaire sur chaque image. Cette approche est plus robuste pendant le maximum de l'eclipse, quand le Soleil devient un croissant fin et que son centre apparent devient difficile a mesurer.
Le script utilise seulement deux images de reference :
- une premiere image, au debut de la sequence ;
- une derniere image, plus tard dans la sequence.
Le centre solaire est detecte sur ces deux references, puis la derive est modelisee comme lineaire dans le temps. Chaque image intermediaire est ensuite translatee selon son timestamp FITS reel.
- lecture des fichiers FITS d'un dossier ;
- tri chronologique par timestamp FITS, pas seulement par nom de fichier ;
- detection automatique du disque solaire sur les deux references ;
- ajustement robuste du cercle solaire ;
- correction de derive lineaire en X et Y ;
- translation subpixel avec interpolation ;
- debayerisation automatique si le header contient
BAYERPAT; - export PNG ou TIFF 16 bits ;
- conversion de dynamique uniforme pour toute la sequence ;
- crop centre sur le Soleil, par defaut a 60% ;
- fichiers de diagnostic en mode debug ;
- CSV de controle avec les shifts calcules.
Python doit etre installe, ainsi que les bibliotheques suivantes :
pip install numpy scipy pillow opencv-pythonastropy est optionnel. Si astropy n'est pas installe, le script utilise un lecteur FITS minimal integre, suffisant pour les FITS 2D simples de cette sequence.
pip install astropyPour creer ensuite une video, installer aussi FFmpeg. Sur Windows :
winget install -e --id Gyan.FFmpegApres installation, il peut etre necessaire de redemarrer VS Code ou le terminal.
Mettre dans le dossier d'entree uniquement les FITS a traiter.
Exemple :
ECLIPSE_DRIFT/
eclipse_align.py
fits/
2026-08-12-1723_0-FH-Solar Filter-Sun_0000.fits
2026-08-12-1725_0-FH-Solar Filter-Sun_0000.fits
...
2026-08-12-1858_4-FH-Solar Filter-Sun_0000.fits
aligned/
Eviter de laisser dans le dossier d'entree :
- des FITS de dimensions differentes ;
- des doublons ;
- des fichiers deja exclus ;
- des copies prefixees, par exemple
abe_....
Le script verifie que toutes les images ont les memes dimensions.
Depuis le dossier du projet :
python eclipse_align.py --input ./fits --first "2026-08-12-1723_0-FH-Solar Filter-Sun_0000.fits" --last "2026-08-12-1858_4-FH-Solar Filter-Sun_0000.fits" --output ./aligned --debugAvec cette commande :
- les FITS sont lus depuis
./fits; - les PNG alignes sont ecrits dans
./aligned; - les fichiers debug sont ecrits dans le dossier des FITS ;
- le crop 60% est applique par defaut ;
- la debayerisation est automatique si
BAYERPATest present.
Dans le dossier --output :
aligned_0001.png
aligned_0002.png
aligned_0003.png
...
alignment.csv
Dans le dossier --input, si --debug est utilise :
debug_first.png
debug_last.png
debug_drift.png
Le CSV contient les informations de controle :
filename
timestamp
alpha
predicted_x
predicted_y
shift_x
shift_y
Ces valeurs permettent de verifier la derive calculee et les translations appliquees image par image.
Ces images servent a valider visuellement le principe de l'alignement avant de regarder toute la sequence.
Montre la detection sur la premiere reference :
- contour detecte ;
- cercle solaire ajuste ;
- centre mesure ;
- coordonnees et rayon.
Montre la detection sur la derniere reference.
Si le rayon detecte librement differe trop de celui de la premiere image, le script peut refaire l'ajustement de la derniere image avec le rayon de la premiere reference. C'est utile quand la derniere image est deja fortement occultee.
Image composite de controle :
- premiere reference en vert ;
- derniere reference en magenta ;
- cercles detectes ;
- centres detectes ;
- fleche jaune de derive ;
- drift X/Y en pixels et pixels/minute.
C'est l'image la plus utile pour valider visuellement le modele de derive.
Lecture du composite :
- le disque vert est la position du Soleil dans la premiere reference ;
- le disque magenta est la position du Soleil dans la derniere reference ;
- les deux cercles doivent avoir un rayon coherent ;
- la fleche jaune montre le deplacement mesure entre les deux centres ;
- le script suppose que les images intermediaires suivent cette derive de maniere lineaire dans le temps ;
- chaque image est ensuite translatee dans le sens inverse pour ramener le Soleil a la position verte de depart.
En resume :
position mesuree au debut -> position mesuree a la fin
C0 -> C1
derive lineaire dans le temps
|
v
correction inverse appliquee a chaque image
Les FITS de la camera couleur peuvent apparaitre comme des images N&B car ils contiennent une matrice Bayer brute.
Par defaut :
--debayer autoLe script lit le champ FITS :
BAYERPAT
et debayerise automatiquement si un motif valide est present.
Les motifs supportes sont :
RGGB
BGGR
GRBG
GBRG
Pour forcer explicitement le motif :
python eclipse_align.py --input ./fits --first "..." --last "..." --output ./aligned --debayer always --bayer-pattern RGGBPour desactiver la couleur et sortir en niveaux de gris :
python eclipse_align.py --input ./fits --first "..." --last "..." --output ./aligned --debayer neverNote : PIPP peut demander un motif different de celui du script. Sur cette sequence, PIPP donne un bon rendu avec GBRG, alors que le script/OpenCV donne le bon rendu avec RGGB. C'est probablement lie aux conventions de lecture verticales du FITS, notamment ROWORDER=BOTTOM-UP.
Par defaut, le script applique :
--crop 60%Cela signifie que l'image finale garde 60% de la largeur et 60% de la hauteur originales, centrees sur le Soleil de la premiere reference.
Exemples :
--crop 60%
--crop 0.6
--crop 75%
--crop 1.0Pour desactiver le crop :
--crop 100%Le crop est calcule une fois a partir de la premiere reference, puis applique identiquement a toute la sequence apres alignement. Cela conserve un cadrage stable.
Les FITS peuvent etre issus d'une camera 12 bits, mais stockes dans un conteneur FITS 16 bits.
Exemple observe :
BITDEPTH = 12
BITPIX = 16
valeurs max reelles autour de 14766
Il ne faut donc pas supposer automatiquement que le blanc vaut 4095.
Par defaut, le script calcule :
- un black point global ;
- un white point global ;
- puis applique la meme conversion a toutes les images.
C'est important pour eviter un pompage artificiel de luminosite dans l'animation.
Pour imposer les valeurs :
--black-point 0 --white-point 14766ou, pour un rendu un peu plus sombre :
--black-point 0 --white-point 18000Par defaut :
--format pngLe script ecrit des PNG 16 bits.
Pour sortir en TIFF 16 bits :
--format tiffLes PNG 16 bits peuvent etre assez legers. Ce n'est pas une compression destructive : le PNG compresse sans perte, et les grands fonds noirs se compressent tres bien.
Par defaut :
--interpolation-order 3Cela utilise une interpolation spline d'ordre 3 via scipy.ndimage.shift, proche d'une interpolation bicubique.
Pour une interpolation plus simple :
--interpolation-order 1Depuis le dossier aligned, ou depuis un dossier contenant les images aligned_0001.png, etc. :
ffmpeg -framerate 6 -i aligned_%04d.png -c:v libx264 -crf 16 -pix_fmt yuv420p eclipse.mp4Pour figer la derniere image 2 secondes :
ffmpeg -framerate 6 -i aligned_%04d.png -vf "tpad=stop_mode=clone:stop_duration=2" -c:v libx264 -crf 16 -pix_fmt yuv420p eclipse.mp4A 6 fps, si l'on veut que la derniere image dure exactement 2 secondes au total, utiliser plutot :
ffmpeg -framerate 6 -i aligned_%04d.png -vf "tpad=stop_mode=clone:stop_duration=1.833" -c:v libx264 -crf 16 -pix_fmt yuv420p eclipse.mp4Pour un master de meilleure qualite :
ffmpeg -framerate 6 -i aligned_%04d.png -vf "tpad=stop_mode=clone:stop_duration=2" -c:v prores_ks -profile:v 3 eclipse_master.movSi les dernieres images deviennent naturellement plus sombres parce que le temps d'exposition n'a pas ete augmente, il peut etre preferable de les retoucher manuellement dans GIMP ou PixInsight.
Conseil :
- garder le point noir stable ;
- remonter progressivement la courbe sur les dernieres images ;
- eviter un auto-stretch different image par image ;
- verifier le rendu dans le MP4 final.
Cette correction est plutot une compensation visuelle qu'une correction photometrique stricte.
--input INPUT
Dossier contenant les FITS.
--first FIRST
Nom du premier FITS de reference.
--last LAST
Nom du dernier FITS de reference.
--output OUTPUT
Dossier de sortie pour les images alignees et alignment.csv.
--black-point BLACK_POINT
Niveau noir impose pour toute la sequence.
--white-point WHITE_POINT
Niveau blanc impose pour toute la sequence.
--crop CROP
Crop centre apres alignement. Defaut : 60%.
--debug
Genere debug_first.png, debug_last.png et debug_drift.png.
--debayer auto|always|never
Controle la debayerisation. Defaut : auto.
--bayer-pattern RGGB|BGGR|GRBG|GBRG
Force le motif Bayer.
--no-radius-refit
Desactive le recalage de la derniere reference avec le rayon de la premiere.
--format png|tiff
Format de sortie 16 bits. Defaut : png.
--interpolation-order 0..5
Ordre d'interpolation scipy. Defaut : 3.
python eclipse_align.py `
--input ./fits `
--first "2026-08-12-1723_0-FH-Solar Filter-Sun_0000.fits" `
--last "2026-08-12-1858_4-FH-Solar Filter-Sun_0000.fits" `
--output ./aligned `
--debug `
--crop 60% `
--debayer autoPuis :
cd aligned
ffmpeg -framerate 6 -i aligned_%04d.png -vf "tpad=stop_mode=clone:stop_duration=2" -c:v libx264 -crf 16 -pix_fmt yuv420p eclipse.mp4

