Prérequis : maîtriser les bases de la programmation Python (variables, boucles, entrées/sorties, fonctions)
Contexte de la mise en œuvre de l'activité : en classe
Ressources, matériel, documents nécessaires : bibliothèque Python (PIL)
Présentation
Alice retrouve une photographie dans ses fichiers et elle aimerait bien se rappeler où et quand elle l'a prise. Elle envisage de la transformer en une carte postale originale.
Nous allons réaliser un programme qui permet d'extraire les métadonnées d'une photographie (localisation et date).
Nous réaliserons également une nouvelle image à partir de la photographie donnée et d'un patron (masque de référence superposé à la photographie pour former la carte postale).
Photo - Patron - Carte postale
Préparation
La bibliothèque Python « PIL » (Python Imaging Library) permet de traiter les images dans de nombreux formats. On l’importe avec from PIL import Image
On ouvre l'image avec img = Image.open("nom_image"), on crée une nouvelle imageavec Image.new("RGB",(l,h))où RGB est le mode couleur et l, h les dimensions.
On utilise la méthode getpixel((x,y)) pour obtenir les informations sur le pixel de coordonnées x, y.
Pour lire les pixels aux coordonnées (5, 3), on donne l'instruction img.getpixel((5,3)))et pour écrire un pixel à ces mêmes coordonnées on aimg.putpixel(5,3),(255,0,0)).
Pour obtenir les métadonnées, il faut importer le module TAGS avec from PIL.ExifTags import TAGS.
Nous pouvons alors afficher ces métadonnées avec :
exif_data = {TAGS[k]: v for k, v in img._getexif().items() if k in TAGS}
print(exif_data)
Traitement des données avec Python
Partie 1 : Extraire la localisation et la date de l'image.
Nous vous proposons le programme à compléter suivant qui utilise trois fonctions vous permettant d'afficher les informations requises dans la console :
from PIL import Image
from PIL.ExifTags import TAGS
def get_coord_gps(exif_data):
lat = coord_degres(exif_data['GPSInfo'][2])
lat_ref = exif_data['GPSInfo'][1]
long = coord_degres(exif_data['GPSInfo'][4])
long_ref = exif_data['GPSInfo'][3]
if lat_ref != "N":
lat *= -1 # équivalent à lat = (-1)*lat
if long_ref != "E":
long *= -1 # équivalent à long = (-1)*long
return lat, long
def coord_degres(coord):
# Conversion des coordonnées GPS en degrés
return coord[0] + (coord[1] / 60.0) + (coord[2] / 3600.0)
def get_date_time(exif_data):
sdate_time = exif_data['DateTime']
ldate_time = sdate_time.split(" ")
ldate = ldate_time[0].split(":")
time = ldate_time[1]
date = ldate[2]+"/"+ldate[1]+"/"+ldate[0]
return date, time
img = Image.open("NYC.jpg")
img.show()
exif_data = {TAGS[k]: v for k, v in img._getexif().items() if k in TAGS}
print(exif_data)
# A compléter !
1. Complétez le programme pour qu'il affiche la localisation GPS (latitude et longitude) ainsi que la date et l'heure de la prise de vue.
Partie 2 : Générer la carte postale
Le patron est réalisé avec les mêmes dimensions que la photographie, avec une couleur primaire (vert : (0, 255, 0)) sur fond blanc (255, 255, 255). Il suffit de lire chaque pixel, dans une double boucle balayant toutes les coordonnées x, y du patron et de vérifier la couleur : si c'est vert, vous recopiez le pixel(x, y) de la photographie dans la nouvelle image et sinon, vous écrivez un pixel blanc.
Attention, la couleur verte (0, 255, 0) n'est pas forcément aussi précise, il est donc obligatoire de prendre une marge de 10 environ sur ces valeurs (0 à 10, 245 à 255, 0 à 10).
2. Ajoutez et complétez le code suivant :
patron = Image.open("patron_NYC.jpg")
patron.show()
l, h = img.size
carte_postale = Image.new("RGB",(l,h))
# A compléter !
Attention, le traitement de l'image peut être long (> 1 min !) suivant la rapidité de votre PC.
Aide sur les fonctions
get_coord_gps(exif_data): permet d'obtenir les coordonnées GPS. Le paramètre "exif_data" est un dictionnaire de dictionnaires qui contient les métadonnées de la photographie. La clé "GPSInfo" a pour valeur le dictionnaire comportant les données de géolocalisation :
'GPSInfo': {0: b'\x02\x02\x00\x00', 1: 'N', 2: (48.0, 52.0, 12.257), 3: 'E', 4: (2.0, 20.0, 11.2598), 5: b'\x00', 6: 83.0, 7: (12.0, 55.0, 35.0), 27: b'G\x00P\x00S\x00\x00\x00', 29: '2018:11:14'}
exif_data['GPSInfo'][2] donne la latitude qu'il faudra multiplier par -1 car l'indicateur est "N"
coord_degres(coord): permet de traduire les coordonnées GPS de la fonction précédente en degrés décimaux :
48.0, 52.0, 12.257 correspond à 48 + 52/60 + 12.257/3600
get_date_time(exif_data): permet d'obtenir la date et l'heure. Le paramètre "exif_data" est un dictionnaire de dictionnaires qui contient les métadonnées de la photographie. La clé "DateTime" a pour valeur une chaine de caractères comportant la date et l'heure de la prise de vue :
'DateTime': '2018:11:14 13:55:51'
On doit d'abord séparer cette chaine en deux avec le caractère espace " " pour avoir la date et l'heure puis encore en trois avec le caractère ":" si l'on veut pouvoir adapter le format (2018:11:14 en 14/11/2018 par exemple).