from PIL import Image
from copy import deepcopy
from math import sqrt,pi,atan2
#récupération de l'image
im=Image.open("cassiopee.jpg")
cassiopée=[[0.6661991329830571, 1.03994281233498], [0.8286901903137861, 0.19165366503676712], [1.3105395308206442, 0.2843792578883825], [1.8009802959719001, 0.0]]
grande_ourse=[[0.3453883269501608, 1.4430731470128877], [0.6593999877978375, 0.15638119997338595], [1.2503485436675665, 6.1890757017675915], [0.981963943474469, 6.278942560696314], [0.6663240160251057, 0.5975152857431754], [1.66780033236181, 0.0]]

constellations=[cassiopée,grande_ourse]

data = list(im.getdata())
r,g,b = im.split()
print(im.size, im.format,im.mode)
#caractéristiques de l'image
s=im.size
m=im.mode
#im.getpixel(())
L=[]
hauteur=im.size[1]#nb de lignes de pixels
largeur=im.size[0]# nb de colonnes de pixels

#on veut la liste de tous les centres
def trouve(im,nombre):#facteur est le facteur de multiplication de la moyenne (60), nombre le nombre d'étoiles de la constellation
    imf2,moyenne=niveau_de_gris(im)
    #print(moyenne)
    #moyenne=moyenne*facteur
    imf3=simplifié(imf2,moyenne)
    #imf3.show()
    B=binaire(imf3)
    nettoyage(B)
    #print(B)
    L,nbLabels=food_fill(B)
    #print(nbLabels)
    #print(L)
    liste_centres=centres(nbLabels,L,nombre)
    #print(liste_centres)
    
def matrice0(hauteur,largeur):#crée une matrice de zéros
    M=[]
    nbLabels=0
    for i in range (hauteur):
        M.append([])
        for j in range (largeur):
            M[i].append(0)
    return M


#inversion (négatif)
def inversion(im):
    imf1=Image.new(m,s)
    for i in range(hauteur):
        for j in range(largeur):
            pixel = im.getpixel((j,i)) # récupération du pixel
        # on calcule le complement à MAX pour chaque composante - effet négatif
            p = (255 - pixel[0], 255 - pixel[1], 255 - pixel[2])
        # composition de la nouvelle image
            imf1.putpixel((j,i), p)
    imf1.show()
    return imf1

#niveau de gris
def niveau_de_gris(im):
    imf2=Image.new(m,s)
    somme=0
    for i in range(hauteur):
        for j in range(largeur):
            pixel = im.getpixel((j,i)) # récupération du pixel
            
# calcul du poids de chaque composante du gris dans le pixel (CIE709:convention européenne)
            gris = int(0.2125 * pixel[0] + 0.7154 * pixel[1] + 0.0721 * pixel[2])
            somme+=gris
# gris = int(0.33 * pixel[0] + 0.33 * pixel[1] + 0.33 * pixel[2])
            p = (gris,gris,gris)

    # composition de la nouvelle image
            imf2.putpixel((j,i), p)
    #imf2.show()
    moyenne=200#intensité moyenne d'un pixel
    return imf2,moyenne

def simplifié(imf2,moyenne): #donne une image avec uniquement les 'valeurs extrêmes' (infonctionelle ici)
    imf3=Image.new(m,s)
    somme=0
    for i in range(hauteur):
        for j in range(largeur):
            pixel = imf2.getpixel((j,i))
            if (pixel[0]+pixel[1]+pixel[2])/3 <moyenne:
                 pixel = (0,0,0)#pixels noirs
                 
            else :
                pixel = (255,255,255)
                imf3.putpixel((j,i), pixel)
        
    #imf3.show()
    return imf3

def binaire(imf3): #prend une image binaire et renvoie une matrice binaire
    B=deepcopy(matrice0(hauteur,largeur))
    for i in range (hauteur):
        for j in range (largeur):
             pixel = imf3.getpixel((j,i))
             if pixel!=(0,0,0):
                 B[i][j]=1
    
    return B


             
def food_fill(B):
    L=deepcopy(matrice0(hauteur,largeur))
    nbLabels=0
    for i in range (hauteur):
        for j in range (largeur):
            if B[i][j]==1:
                nbLabels+=1
                connexites(i,j,B,L,nbLabels)            
    #print(nbLabels)       
    return L,nbLabels
def nettoyage(B):
    for i in range(hauteur):
        B[i][0],B[i][largeur-1]=0,0
    for j in range(largeur):
        B[0][j],B[hauteur-1][j]=0,0 #pour éviter les erreurs 'out of range'
    

def connexites(i,j,B,L,nbLabels):#récursif
    pixel=B[i][j]
    if pixel==1:
        L[i][j]=nbLabels
        B[i][j]=0
        if B[i][j+1]==1:
            connexites(i,j+1,B,L,nbLabels)
        if B[i-1][j]==1:
            connexites(i-1,j,B,L,nbLabels)
        if B[i][j-1]==1:
            connexites(i,j-1,B,L,nbLabels)
        if B[i+1][j]==1:
             connexites(i+1,j,B,L,nbLabels)
             
def centres(nbLabels,L,nombre):
    liste_coord=[]
     #liste des coordonnées "intéréssantes"
    liste_centres=[]
    for k in range (nbLabels):
        liste_coord.append([])
    for i in range(hauteur):
        for j in range (largeur):
            if L[i][j]!=0:
                liste_coord[(L[i][j]-1)].append([i,j])
    N=len(liste_coord)
    étoiles=liste_coord
    for s in range(N):
        x,y=0,0
        for a in range(len(étoiles[s])):
            x+=étoiles[s][a][0]
            y+=étoiles[s][a][1]
        X=x/len(étoiles[s])
        Y=y/len(étoiles[s])
        liste_centres.append([X,Y])
    return liste_centres

def compare(L1,L2):
    if len(L1)!=len(L2):
        return False
    n=len(L1)
    points_communs=0
    for i in range(n):
        for j in range(n):
            if abs(L1[i][0]-L2[j][0])<0.05 and abs(L1[i][1]-L2[j][1])<0.05:
                points_communs+=1
    if points_communs==n:
        return True
    else:
        return False

        


        



