##Traitement d'images

##1 : Préparation de l'environnement
#On se place dans le bon répertoire
import os
os.chdir("chemin du répertoire images")

print(os.getcwd())  #Affiche le répertoire dans lequel vous vous trouvez, pour vérification

#Importation des modules pour le traitement d'images
from PIL import Image
import numpy as np


#Ouverture de l'image du dauphin.
imageDauphin = Image.open('dauphinNB.png') # Lecture du fichier contenant l'image
imageDauphin.show() # Affichage de l'image
tabImageDauphin = np.array(imageDauphin) #Création d'un tableau numpy contenant les données de l'image.
imageDauphin2 = Image.fromarray(tabImageDauphin) #Création de l'image correspondante au tableau numpy


##2.Implémentation d'une image
"""
Question 1 :
"""
print(len(tabImageDauphin)) #La hauteur de l'image i.e. son nombre de lignes
print(len(tabImageDauphin[0])) #La largeur de l'image i.e. son nombre de colonnes

print(tabImageDauphin.shape) #Le couple des dimensions de l'image : (hauteur,largeur)

"""
Question 2 :
"""
n,m = tabImageDauphin.shape

print(tabImageDauphin[0][0]) #Pixel en haut à gauche
print(tabImageDauphin[n-1][0]) #Pixel en bas à gauche
print(tabImageDauphin[n-1][m-1]) #Pixel en bas à droite
print(tabImageDauphin[0][m-1]) #Pixel en haut à droite


##3.Algorithmes classiques
#Binarisation
"""
Question 3 :
"""
def binariser(image,s) :
    tabImage = np.array(image) #Conversion de l'image en tableau numpy
    ligne,colonne = tabImage.shape #Dimension de l'image
    #On parcourt tous les pixels de l'image
    for i in range(ligne):
        for j in range(colonne):
            #Si le pixel i,j est supérieur au seuil
            if tabImage[i][j] > s :
                tabImage[i][j] = 255 #On le met en blanc
            #Sinon
            else :
                tabImage[i][j] = 0 #On le met en noir
    return Image.fromarray(tabImage) #On renvoie l'image reconvertit en image

binariser(imageDauphin,75).show()
binariser(imageDauphin,150).show()

#Négatif
"""
Question 4 :
"""
def negatif(image) :
    tabImage = np.array(image) #Conversion de l'image en tableau numpy
    ligne,colonne = tabImage.shape #Dimension de l'image
    #On parcourt tous les pixels de l'image
    for i in range(ligne):
        for j in range(colonne):
            tabImage[i][j] = 255 - tabImage[i][j] #On inverse la couleur du pixel i,j
    return Image.fromarray(tabImage) #On renvoie l'image reconvertit en image

negatif(imageDauphin).show()

#Retourner
"""
Question 5 :
"""
def retourner(image) :
    tabImage = np.array(image) #Conversion de l'image en tableau numpy
    ligne,colonne = tabImage.shape #Dimension de l'image
    #On parcourt tous les pixels de la moitié gauche de l'image
    for i in range(ligne):
        for j in range(colonne//2):
            #On inverse le pixel (i,j) avec le pixel (i,colonne-1-j) (symétrique vertical)
            tabImage[i][j], tabImage[i][colonne-1-j]= tabImage[i][colonne-1-j], tabImage[i][j]
    return Image.fromarray(tabImage) #On renvoie l'image reconvertit en image

retourner(imageDauphin).show()

#Rotation
"""
Question 6 :
"""
def pivoter(image) :
    tabImage = np.array(image) #Conversion de l'image en tableau numpy
    ligne,colonne = tabImage.shape #Dimension de l'image
    nvtabImage = np.zeros((colonne,ligne),dtype=np.uint8) #Nouvelle image de dimensions contraires remplie de 0
    #On parcourt tous les pixels de la nouvelle image
    for i in range(colonne):
        for j in range(ligne):
            nvtabImage[i][j] = tabImage[ligne-1-j][i] #Le pixel (i,j) de la nouvelle image est le pixel (ligne-1-i,j) de l'ancienne
    return Image.fromarray(nvtabImage) #On renvoie l'image reconvertit en image

pivoter(imageDauphin).show()

#Augmentation du contratse
"""
Question 7 :
"""
imageMeduse = Image.open('meduseSombre.png') # Lecture du fichier contenant l'image
imageMeduse.show() # Affichage de l'image
tabImageMeduse = np.array(imageMeduse) #Création d'un tableau numpy contenant les données de l'image.

def calculHistogramme(image) :
    tabImage = np.array(image) #Conversion de l'image en tableau numpy
    ligne,colonne = tabImage.shape #Dimension de l'image
    hist = [0 for i in range(256)] #Nombre de pixels de chaque couleur
    #On parcout tous les pixels de l'image
    for i in range(ligne):
        for j in range(colonne):
            hist[tabImage[i][j]] += 1 #On augmente de 1 le nombre de pixels de la couleur du pixel (i,j)
    return hist #On renvoie l'histogramme

#Importation du module matplotlib pour faire des tracés
from matplotlib import pyplot as plt

HistMeduse = calculHistogramme(imageMeduse) #Histogramme de l'image de méduse
plt.plot([i for i in range(256)], HistMeduse) #Tracer les valeurs de l'histogramme de la méduse en fonction de la couleur des pixels
plt.show() #Afficher le graphe

"""
Question 8 :
"""
def minimum(hist) :
    i=0 #Indice de parcours
    #Tant que la liste n'est pas finie et qu'on n'est pas tombé sur 0
    while i<len(hist) and hist[i]==0 :
        i += 1 #On continue
    return i

def maximum(hist) :
    i=len(hist)-1 #Indice de parcours
    #Tant que la liste n'est pas finie et qu'on n'est pas tombé sur 0
    while i>=0 and hist[i]==0 :
        i -= 1 #On continue
    return i

def normaliserImage(image):
    tabImage = np.array(image) #Conversion de l'image en tableau numpy
    ligne,colonne = tabImage.shape #Dimension de l'image
    hist = calculHistogramme(image) #Histogramme de l'image
    min,max = minimum(hist),maximum(hist) #Couleur min et max de l'image
    nvtabImage = np.zeros((ligne,colonne),dtype=np.uint8) #Nouvelle image de mêmes dimensions remplie de 0
    #On parcourt les pixels de la nouvelle image
    for i in range(ligne):
        for j in range(colonne):
            nvtabImage[i][j] = ((tabImage[i][j] - min)/(max-min))*255//1 #Normalisation du pixel (i,j)
    return Image.fromarray(nvtabImage) #On renvoie la nouvelle image au format Image

imageMeduseNorm = normaliserImage(imageMeduse) #Image de la méduse normalisée
imageMeduseNorm.show()

HistNormMeduse = calculHistogramme(imageMeduseNorm) #Histogramme de l'image de méduse normalisée
plt.plot([i for i in range(256)], HistNormMeduse) #Tracer les valeurs de l'histogramme de la méduse normalisée en fonction de la couleur des pixels
plt.show() #Afficher le graphe




