Table des matières

Étiqueter des photos à partir des métadonnées GPS

Dans cet exercice, on vous fournit

Nous souhaitons, pour chaque fichier image,

  1. lire les métadonnées GPS du fichier,
  2. chercher la ville la plus proche parmi celles présentes dans la liste des villes,
  3. modifier le nom du fichier image pour qu'il prenne le nom de la ville correspondante.

Acquisition des métadonnées GPS

Nous allons utiliser la bibliothèque PIL.

from PIL import Image
from PIL.ExifTags import GPSTAGS, TAGS


# Exemple de l'ouverture d'une image de nom '1.jpg'
with Image.open('1.jpg') as image:
    metadata = image._getexif()
    # metadata est dictionnaire avec clé peu explicites,
    # grâce à TAGS on renomme ces clés
    labeled_metadata = {TAGS.get(key):val for key, val in metadata.items()}
    # labeled_metadata contient une clé GPSInfo qui elle aussi
    # a des clés peu compréhensible. On peut réétiqueter :
    gps = {GPSTAGS.get(key,key):value for key, value in labeled_metadata['GPSInfo'].items()}
    # maintenant gps contient des données exploitables

Exemple de résultat dans gps :

{
    'GPSLatitude': ((55, 1), (52, 1), (20922, 679)),
    'GPSLongitudeRef': 'E',
    'GPSLongitude': ((37, 1), (50, 1), (77312, 2183)),
    'GPSLatitudeRef': 'N',
    'GPSVersionID': b'\x02\x03\x00\x00'
}

Conversion des données GPS en degrés ordinaire

Prenons le résultat précédent, en ce qui concerne la latitude. Pour la latitude, on trouve la donnée ((55, 1), (52, 1), (20922, 679)). Il faut comprendre qu'il s'agit d'un angle de $\frac{55}{1}$ degrés et $\frac{52}{1}$ minutes et $\frac{20922}{679}$ secondes d'arc.

Vous devez donc prévoir une fonction faisant la conversion vers l'angle correspondant qui serait ici : $$angle = \frac{55}{1} + \frac{52}{1} \times \frac{1}{60} + \frac{20922}{679} \times \frac{1}{3600}$$

Il faut aussi prévoir un signe. Dans l'exemple, gps["GPSLatitudeRef"] == "N". C'est donc une latitude Nord, dans ce cas l'angle est compté en plus. Dans le cas Sud, il aurait fallu compter l'angle négativement.

Pour la longitude, le côté positif est "E" et le côté négatif est "W".

Recherche de la ville la plus proche

il s'agit d'ouvrir le fichier worldcities.csv et d'extraire les informations nécessaires. Il nous suffit de connaître pour chaque ville ses coordonnées GPS.

Ensuite, vous devez chercher la ville la plus proche de la localisation GPS qui nous intéresse, celle extraite de l'image.

Voici une formule : supposons que vous disposiez des longitude et latitude pour deux positions a et b, la distance entre ces deux positions sera :

$$D_{ab} = R \arccos(\sin(latitude_a) \sin(latitude_b) + \cos(longitude_a - longitude_b) \cos(latitude_a) \cos(latitude_b))$$

Les angles doivent être convertis en radians. Avec pour la Terre, $R \simeq 6\,378\,km$.

En python, on pourra importer : from math import cos, sin, acos, radians. La fonction radians assure la conversion degrés → radians.

Système de fichier

Vous devez parcourir le dossier à la recherche des fichiers *.jpg et après traitement vous devez les renommer. Voici comment faire :

import os

# renommer :
os.rename('ancien_nom.jpg', 'nouveau_nom.jpg')

# lister les fichiers *.jpg du répertoire courant
fichiers = [f for f in os.listdir('./') if f.endswith('.jpg')]

C'est à vous !

Vous disposez de tous les éléments nécessaires, à vous de produire le script Python !