Les données spectriques imzML
sous python
Le format imzML est un format particulier open dont la structure implique à chaque fois un couple de deux fichiers : les spectres (.ibd) et leurs caractéristiques (métadonnées au format imzML).
1- Installer le parser pyimzml
On peut installer imzML avec pip, mais on peut rencontrer des problèmes d'installation avec le module complémentaire wheezy.template. Il faut aussi avoir installé sur sa machine Microsoft Visual C++.
Installation via pip :
pip install pyimzml
2- Ouvrir les données
Décompiler le fichier imzML
import easygui
p = ImzMLParser(easygui.fileopenbox())
for idx, (x,y,z) in enumerate(p.coordinates):
mzs, intensities = p.getspectrum(idx)
Ouvrir l'ibd (format binaire)
f = open("C:/Users/masse/Google Drive/gnagna.ibd", 'ibd') # opening a binary file
content = f.read() #reading all lines
3- Interpréter les spectres
Si on suit l'image de cette publication, on comprendra qu'on va pouvoir utiliser les coordonnées indiquées dans le fichier imzML afin d'extraire chaque spectre identifié soumis au laser.
Ce spectre va pouvoir ensuite être interprété, converti en une valeur de niveau de gris, ou une composante rgb de couleur.
L'affichage direct des valeurs du fichier binaire ne fonctionne pas :
content[0:100]
b'\x1f\xf0w`a\xb5K.\xb3b\x0f\x91\xd4R}\xdf\x00\x00\x00\x00\x05\x1c\x86@\x00\x00\x00\x80d,\x86@\x00\x00\x00\x80a9\x86@\x00\x00\x00\xe0\xfe?\x86@\x00\x00\x00\xc0\xf4\x88\x86@\x00\x00\x00@u\xa5\x86@\x00\x00\x00 S\xc3\x86@\x00\x00\x00\xc0\x8b\xce\x86@\x00\x00\x00\xe0\xa3\xda\x86@\x00\x00\x00\x00\xe3\x1e\x87@\x00\x00\x00\xe0'
Mais on peut procéder ainsi :
liste = []
for i in range(0,100) :
liste.append(content[i])
print(liste)
import matplotlib.pyplot as plt
plt.plot(list) ; plt.show()
A l'expert donc de croiser l'imzML et ibd pour en extraire les spectres pixel par pixel et interpréter ces spectres.
4- Reconstituer une image
On va ainsi pouvoir exploiter l'interprétation de chaque spectre pour reconstruire une image de l'échantillon passé au laser.
Imaginons que j'ai 80000 pixels à répartir sur une image de dimension L*H de 400X200.
Chaque pixel après analyse se fera attribué une valeur de rouge, vert et ou bleu. Simulons les valeurs des 3 composantes de ces pixels :
from numpy.random import normal as normal
import numpy as np
red = normal(loc=100, scale=40, size=400) ; red = sorted(red) ; red = list(red)*200 ; red = np.array(red) ; red= [int(valeur) for valeur in red]
green = normal(loc=60, scale=20, size=400); green= list(green)*200 ; green= np.array(green) ; green= [int(valeur) for valeur in green]
blue= normal(loc=80, scale=20, size=80000); blue= [int(valeur) for valeur in blue]
# Histogramme
import pandas as pd
tablo = pd.DataFrame({"red":red,"green":green,"blue":blue})
import matplotlib.pyplot as plt
tablo.plot(kind='hist',alpha=0.5,bins=20,color=["red","green","blue"]) ; plt.show()
Compilons maintenant ces pixels en image :
#initialiser une image vide de 400 sur 200
image = np.empty([400,200,3])
red = np.reshape(np.array(red),(400,200)) # 400 : hauteur, 200 : largeur
green = np.reshape(np.array(green),(400,200))
blue = np.reshape(np.array(blue),(400,200))
image [:,:,0] = red
image [:,:,1] = green
image [:,:,2] = blue
# Conversion au format pixel (valeurs entières entre 0 et 255)
image = image.astype(np.uint8)
from PIL import Image
plt.imshow(image)
plt.show()
Et voilà, l'image est convertie à partir d'une jeu de données. Suivre ce lien de mon site internet pour en savoir plus sur la manipulation des images.