Cet outil permet d'aligner une série de photos issues d'une rafale sur un sujet (par exemple son oeil) puis exporte les photos alignées dans un dossier ou directement une vidéo (avec un son de déclencheur en option).
Il a été développé et testé uniquement sur Mac. Il devrait aussi fonctionner sous Windows mais n'y a pas été testé (voir Sous Windows pour les différences).
Télécharger
- pinpoint.pyv1.0.0 · SHA-256 c7eb20337b36fa6c… Le script : un seul fichier Python, son de déclencheur inclus.
- declencheur_sony_a7ii.wavSHA-256 c68d67c941c9d415… Déclenchement Sony A7 II
Sans garantie
Cet outil réalisé avec Claude est fourni sans aucune garantie. Vous l'utilisez sous votre seule responsabilité. Le script ne modifie jamais les photos d'origine et refuse d'exporter dans leur dossier, mais gardez toujours une sauvegarde de vos photos.
Exemples
Voici la sortie vidéo de l'outil sur trois rafales de busard des roseaux réalisées à Jersey alignées sur l'œil :
Installation
Il faut Python 3.9 ou plus récent. Le plus simple : l'installeur de python.org.
À faire une seule fois, dans le Terminal, depuis le dossier où se trouve pinpoint.py (ici Téléchargements) :
cd ~/Downloads
python3 -m venv pinpoint-env
pinpoint-env/bin/python3 -m pip install PySide6 opencv-python numpy imageio-ffmpeg
L'environnement virtuel est ainsi créé et les bibliothèques installées.
Ensuite, pour lancer l'outil, il suffit d'utiliser le Python de l'environnement virtuel (pour éviter d'avoir à activer l'environnement virtuel) sur votre dossier de photos (ou sans argument si vous souhaitez indiquer le dossier plus tard) :
pinpoint-env/bin/python3 pinpoint.py ~/Photos/serie
L'outil lit les photos en JPEG, PNG et TIFF (8 ou 16 bits) mais pas les fichiers RAW. En option, exiftool (brew install exiftool) permet de recopier les métadonnées des photos d'origine sur les photos exportées.
Sous Windows
L'outil n'a été développé et testé que sur Mac, mais il repose sur des bibliothèques qui existent aussi sous Windows (Qt, OpenCV, ffmpeg) et devrait donc y fonctionner avec quelques adaptations.
Il faut installer Python si vous ne l'avez pas déjà depuis python.org. Les commandes sont les mêmes que sur Mac, dans l'invite de commandes, avec py à la place de python3 et Scripts\python à la place de bin/python3. À faire une seule fois (dans le dossier où vous avez mis l'outil) :
py -m venv pinpoint-env
pinpoint-env\Scripts\python -m pip install PySide6 opencv-python numpy imageio-ffmpeg
Puis, pour lancer l'outil (avec le dossier des photos ou sans argument si vous souhaitez indiquer le dossier plus tard) :
pinpoint-env\Scripts\python pinpoint.py "C:\Photos\serie"
Les autres différences entre Mac et Windows :
- exiftool (optionnel) : il n'y a pas de
brewsous Windows. Il faut télécharger la version Windows sur exiftool.org, renommerexiftool(-k).exeenexiftool.exeet le placer dans un dossier duPATH. Sans exiftool, l'export fonctionne quand même mais sans les métadonnées. - Chemins avec accents : sous Windows, OpenCV ne lit pas correctement les chemins qui contiennent des accents ou des caractères spéciaux (par exemple
C:\Users\Rémi\Images). Il vaut mieux placer la série dans un dossier au chemin simplifié (par exempleC:\Photos\serie). - Raccourcis : Ctrl remplace ⌘, Alt remplace ⌥ et Maj remplace ⇧ (voir le tableau des raccourcis).
- Pavé tactile : le déplacement dans l'image avec deux doigts ne fonctionne que sur Mac. Sous Windows, vous vous déplacez en faisant glisser l'image et la molette sert à zoomer.
- Vidéo et son : ffmpeg est installé avec
imageio-ffmpeg, il n'y a rien d'autre à installer.
Utilisation
1. Sélectionner une séquence de photos
Commencez par choisir une séquence continue de photos, c'est-à-dire des photos qui se suivent dans la rafale, sans trou au milieu. Copiez-les dans un dossier à part, puis ouvrez ce dossier dans l'outil (avec « Ouvrir un dossier… » ou en l'indiquant au lancement).
L'outil prend toutes les photos du dossier, dans l'ordre de leur nom de fichier. S'il manque des photos au milieu de la série, le sujet fera un saut dans la vidéo. Une photo ratée peut quand même être écartée ensuite avec la touche S.
2. Pointer l'œil
Cliquez sur l'œil du sujet (ou sur l'élément à suivre) sur chaque photo. L'outil calcule ensuite le décalage à appliquer pour que l'élément se retrouve au même endroit que sur la photo de référence (marquée d'une ★, que vous pouvez changer avec la touche R).

Si le sujet se rapproche ou s'éloigne pendant la rafale, l'option « Normaliser la taille » ajoute un second repère fixe (par exemple la pointe du bec). L'outil compare alors la distance entre l'œil et ce repère sur chaque photo pour remettre le sujet à la même taille.
3. Vérifier le pointage
La touche O affiche la photo de référence en transparence par-dessus la photo en cours, ce qui permet de vérifier que l'œil tombe bien au même endroit.

4. Cadrer
Le cadre final se règle avec plusieurs options :
- « Pas de bords noirs » garde le cadre dans la zone commune à toutes les photos. Si cette zone est trop petite, vous pouvez écarter les photos où le sujet est le plus décalé (touche S).
- Le ratio (3:2, 16:9, 1:1, 4:5…), la taille du cadre et sa position (⇧ + glisser).
- La position de l'œil dans le cadre : comme sur la référence, au centre, sur un tiers ou à l'endroit de votre choix.
Pendant le réglage, toutes les photos alignées sont superposées, ce qui permet de voir tout de suite si une aile sort du cadre. Le mode Assombrir garde le pixel le plus sombre de la série (pratique pour un sujet sur un ciel clair), Éclaircir garde le plus clair et Moyenne mélange toutes les photos. Les zones en rouge sont celles qui ne sont pas couvertes par toutes les photos.

5. Régler
Les réglages d'exposition, de contraste, de hautes lumières, d'ombres, de saturation et de température s'appliquent à toute la série pour gagner du temps et pour éviter que la luminosité varie d'une image à l'autre dans la vidéo. La touche A permet de comparer avant et après. Il faut trouver un compromis qui convient à l'ensemble.
6. Exporter les photos (option 1)
Les photos alignées sont exportées dans un dossier à part (par défaut <dossier>_aligne), avec le même nom que l'original, au format d'origine, en JPEG ou en TIFF (le 16 bits est conservé en TIFF). Si exiftool est installé, les métadonnées des photos d'origine sont recopiées.
7. Exporter la vidéo (option 2)
L'outil peut aussi créer directement une vidéo MP4 (H.264) à partir de la série, avec plusieurs réglages :
- la cadence, de 1 à 120 images par seconde (un rythme de 15 images/secondes fonctionne bien pour avoir le temps d'apprécier les images) ;
- une pause sur la dernière photo ;
- la résolution (HD, QHD ou 4K), sans jamais agrandir les photos.

En option, un son de déclencheur peut être ajouté à chaque photo. Vous pouvez choisir l'enregistrement d'un Sony A7 II ou votre propre fichier audio.
Sauvegarde
Tout le travail est enregistré automatiquement dans un fichier pinpoint_project.json placé à côté des photos. En rouvrant le dossier, vous reprenez là où vous vous étiez arrêté.
Raccourcis
| Action | Mac | Windows |
|---|---|---|
| Placer l'œil (puis le 2e repère) | clic | clic |
| Placer / déplacer le 2e repère | ⌥ + clic | Alt + clic |
| Déplacer le cadre | ⇧ + glisser | Maj + glisser |
| Se déplacer dans l'image | glisser, ou deux doigts sur le trackpad | glisser |
| Zoomer | pincer, molette, + / − | molette, + / − |
| Suivante / précédente | → ou Espace / ← | → ou Espace / ← |
| Référence | R | R |
| Ignorer la photo | S | S |
| Effacer les points | ⌫ | Retour arrière ou Suppr |
| Superposer la référence / toutes les photos | O / T | O / T |
| Avant / après réglages | A | A |
| Ajuster / taille réelle | F / Z | F / Z |
| Ouvrir / exporter | ⌘O / ⌘E | Ctrl+O / Ctrl+E |
Sous le capot
Le calcul de l'alignement
for name in sess.names:
if not sess.complete(name, n_pts):
continue
e = sess.images[name]
p, (W, H) = e["pts"], e["size"]
s = 1.0
if n_pts == 2:
d = math.dist(p[0], p[1])
if d < 1:
continue
s = d_ref / d
ox, oy = T[0] - s * p[0][0], T[1] - s * p[0][1]
tf[name] = (s, ox, oy)
ix0, iy0 = max(ix0, ox), max(iy0, oy)
ix1, iy1 = min(ix1, ox + s * W), min(iy1, oy + s * H)
Chaque photo reçoit une échelle s et un décalage (ox, oy) : un point p de la photo se retrouve en s × p + (ox, oy), ce qui place l'œil sur la cible T. Les deux dernières lignes calculent la zone couverte par toutes les photos. L'outil corrige seulement la position et la taille, pas la rotation.
La superposition
if mode == "mean":
acc += w.astype(np.float32) * m[..., None]
else:
inside = (m > 0.99)[..., None]
cand = np.where(inside, w, ext)
ext = np.minimum(ext, cand) if mode == "min" else np.maximum(ext, cand)
cnt += m
Chaque photo recalée (w) est combinée avec les précédentes en tenant compte de son masque de couverture (m), et cnt compte le nombre de photos qui couvrent chaque pixel.
Le son du déclencheur
Un son est placé au moment de chaque photo. Sur une rafale rapide, les sons se chevauchent et un limiteur doux évite la saturation.
def build_audio(n_photos, total_frames, fps, sound, volume):
n = int(math.ceil(total_frames / fps * AUDIO_SR))
out = np.zeros(n, np.float32)
snd = sound * volume
for i in range(n_photos):
a = int(round(i / fps * AUDIO_SR))
b = min(n, a + len(snd))
if a < n:
out[a:b] += snd[: b - a]
peak = np.abs(out).max()
if peak > 0.98: # rafale rapide : sons superposés
out = np.tanh(out / peak * 1.5) / np.tanh(1.5) * 0.98
return out