Redresser une image ... de façon à ce quelle soit alignée sur les coordonnées équatoriales

1. Point de départ

Une très grosse image de 5568 x 3712 pixels obtenue après empilement d’une série de photos en "pied fixe", c’est à dire sans orientation définie.
La grosse étoile est Alpha du Cocher (Capella).
En voici une réduction :

2. La mission, si vous l’acceptez...

Il faut faire tourner l’image de façon à l’aligner selon la direct Nord-Sud des lignes équatoriales.
Si possible, il faut le faire de façon automatique.
Si vous avez lu les articles précédents sur Astrometry (et Python), vous savez que l’on peut récupérer cette information dans le fichier de résultats (resul.txt) générés par la commande "solve-fields".
Encore faut-il récupérer cette information par programme de façon à ne pas avoir à l’entrer à la main.

3. Une difficulté quasi-insurmontable

En ne disposant que d’un ordinateur familial, la recherche sur une aussi grosse image risque de ne pas aboutir : le volume d’information à traiter est trop grand.
Pour rendre la recherche possible, on a imaginé de découper un petit rectangle dans le centre de l’image et de demander à Astrometry de faire le travail de recherche sur lui.
Le logiciel s’en sort alors très bien et très vite et il n’y a plus qu’à faire tourner la grosse image de l’angle récupéré.

4. Comment découper un rectangle dans le centre d’une image ?

Sous Linux, tout est facile : un outil qui sait faire cela de façon efficace et rapide existe : Imagemagic.
C’est un logiciel en ligne de commande (que l’on pourra donc appeler depuis Python) et la syntaxe est la suivante :

convert  source.jpg -gravity center -crop 600x600+0+0 cible.jpg

source.jpg et cible.jpg désignent respectivement la grande image et le résultat de la découpe.
La taille de celle-ci a été choisie de 600 pixels sur 600 pixels (c’est un carré).

5. Récupérer l’angle de rotations, puis faire tourner l’image

Cela se fait grâce à une fonction en Python qui lit le fichier de résultats et recherche la ligne contenant le mot "rotation".
Ayant trouvé celle-ci, elle découpe la portion de la ligne qui contient l’information puis la transmet, sous la forme d’un nombre à virgule, à la partie du programme qui en a besoin.
(la variable "faux" contient une valeur angulaire très improbable :
faux = 999999.)

def angleRot():
        """
        Lecture du fichier contenant entre autre l'angle
      dont il faut faire tourner
        l'image pour qu'elle soit alignée sur
       les coordonnées équatoriales
        """
        ang = faux
        fichier = open("resul.txt", "r")
        contenu = fichier.readlines()
        for ligne in contenu:
                if ligne.find("rotation") > 0:
                        ang = ligne[27:36]
        return float(ang)

L’angle récupéré est alors transformé en argument utilisable par le programme qui va faire tourner l’image.

angle = angleRot()
if angle < faux:
        print("L'angle restitué est : ",angle)
        anglestr =str(-1 * (180. +angle))
        rotation ="convert -rotate "+anglestr+" "+image+".jpg "
      +redressee+".jpg"
        os.system(rotation)
else:
        print("Erreur de lecture de l'angle")

Vous avez remarqué, sans doute, que la rotation est à nouveau effectuée en utilisant Imagemagic.

6. Résultat

Ça marche ou ça marche pas ?
Voici, très réduite en taille l’image obtenue :

En plein définition, voici la portion centrée sur Capella :

Et une capture dans "Carte du Ciel" d’une zone équivalente :

Manifestement cela a fonctionné.

7. Le code du programme Python qui a fait le travail

L’ensemble du travail s’effectue en moins de dix secondes.
Ma machine est rapide, certes, mais ces logiciels sont incroyablement efficaces.
Une machine lente mettra une minute, peut-être. Et alors ?

# -*- coding:Utf-8 -*-
"""
        Expérimenter les découpes avec Imagemagic
        Récupérer l'angle de rotation
       dans le fichier texte de résultats
        Faire tourner l'image de l'angle récupéré
        lerautal - janvier 2018
"""
from __future__ import print_function
import time
import os

#~ -  -  -  -   -  - -  -fonctions-  -  -  - -  -  - -  -  - -  - -
def angleRot():

        ang = faux
        fichier = open("resul.txt", "r")
        contenu = fichier.readlines()
        for ligne in contenu:
                if ligne.find("rotation") > 0:
                        ang = ligne[27:36]
        return float(ang)

       
#~ -  -   -   - Zone des variables d'initialisation  -   -   -  
debut = time.time()

reptravail         = os.getcwd()+"/"        # répertoire de travail
repannex        = reptravail + "/generes/"
image                 =         'coch'        # nom du fichier
decoupe         =         image+"_decoupe"
redressee        =        image+"_redressee"
decouper         =  "convert "+image+".jpg -gravity center -crop 600x600+0+0 "+decoupe+".jpg"
chaine105        ="solve-field  --scale-unit arcsecperpix --scale-low 8 --scale-high 9 "+reptravail+ decoupe +".jpg   --dir generes --out "+decoupe+" --overwrite > resul.txt"
faux                         = 999999.

#~ -  -   -   - Partie principale -   -   -   -   -   -   -   -

#~ Découpage de la partie centrale de l'image
os.system(decouper)

#~ Recherche des éléments de l'image
os.system(chaine105)

#~ Récupération de l'angle de rotation
angle = angleRot()
if angle < faux:
        print("L'angle restitué est : ",angle)
        anglestr =str(-1 * (180. +angle))
        rotation ="convert -rotate "+anglestr+" "+image+".jpg "+redressee+".jpg"
        os.system(rotation)
else:
        print("Erreur de lecture de l'angle")
        #~ break

fin = time.time()
print("temps écoulé en minutes : ", (fin - debut)/ 60)
print("soit : ",(fin - debut),"  secondes")