Explorar o código

ajout laplacien et svg

Hvrnbi hai 5 meses
pai
achega
3e823e2a37
Modificáronse 1 ficheiros con 182 adicións e 10 borrados
  1. 182 10
      main.py

+ 182 - 10
main.py

@@ -1,14 +1,15 @@
 ### Modules ###
 ### Modules ###
 
 
-from PIL import Image
+from PIL import Image, ImageFilter
 from numpy import asarray, ndarray, array, uint8, delete
 from numpy import asarray, ndarray, array, uint8, delete
-from random import choices, randint
+from random import choices, randint, random
 from copy import deepcopy
 from copy import deepcopy
+import drawsvg as dw
 
 
 
 
 ### Fonctions ###
 ### Fonctions ###
 
 
-def import_image(chemin: str, resize: bool = False) -> ndarray :
+def import_image(chemin: str, resize: bool = False, lap: bool = False) -> ndarray :
     """Charge l'image donnée, la passe en nuances de gris, et la convertit en tableau (de numpy)"""
     """Charge l'image donnée, la passe en nuances de gris, et la convertit en tableau (de numpy)"""
 
 
     ## Chargement de l'image ## 
     ## Chargement de l'image ## 
@@ -34,7 +35,9 @@ def import_image(chemin: str, resize: bool = False) -> ndarray :
     image = image.convert("L")
     image = image.convert("L")
 
 
     if resize:
     if resize:
-        image = image.resize((300, 400))
+        image = image.resize((400, 400))
+    if lap:
+        image = image.filter(ImageFilter.FIND_EDGES)
 
 
 
 
     ## Conversion en tableau ##
     ## Conversion en tableau ##
@@ -118,7 +121,7 @@ def generer_clous_plus_clous_aleatoires(tab_img):
 
 
     liste_res = generer_clous(tab_img)
     liste_res = generer_clous(tab_img)
 
 
-    for i in range(0, 200):
+    for i in range(0, 400):
         liste_res.append((randint(20, l - 20), randint(20, h - 20), i + 4))
         liste_res.append((randint(20, l - 20), randint(20, h - 20), i + 4))
     
     
     return liste_res
     return liste_res
@@ -314,6 +317,55 @@ def trouve_meilleure_droite_blanche(img1: ndarray, img2: ndarray, clou_dep: tupl
     return (meilleur_clou, red_err)
     return (meilleur_clou, red_err)
 
 
 
 
+def generer_clous_lap(tab_img: ndarray) -> list:
+    """Génère un tableau qui contient des tuples qui représentent des clous : deux coordonnées et un numéro de côté -> 0 pour le haut, 1 pour la droite, 2 pour le bas, 3 pour la gauche"""
+    liste_res = []
+    
+    # On crée la matrice qui contient pour chaque pixel, la somme de sa valeur et de celle de tous les pixels d'avant
+    tab_somme = somme_cumulative_matrice(tab_img)
+    # Le dernier élément est la somme de la valeur de tous les pixels
+    somme_valeurs_px = tab_somme[-1][-1]
+
+    for i in range(600):
+        nb_rd = random() * somme_valeurs_px
+        pixel = trouve_pixel(tab_somme, nb_rd)
+        clou = (pixel[1], pixel[0], i)
+        liste_res.append(clou)
+        
+
+    return liste_res
+
+
+def somme_cumulative_matrice(tab: ndarray) -> list:
+    """Renvoie la somme cumulative de la matrice"""
+    liste_res = []
+
+    for i in range(len(tab)):
+        liste_res.append([])
+        for j in range(len(tab[i])):
+            if j == 0:
+                if i == 0:
+                    liste_res[i].append(int(tab[i][j]) ** 2)
+                else:
+                    liste_res[i].append(int(tab[i][j]) ** 2 + liste_res[i - 1][-1])
+            else:
+                liste_res[i].append(int(tab[i][j]) ** 2 + liste_res[i][j - 1])
+
+    return liste_res
+    
+
+def trouve_pixel(tab: list, nb: float) -> tuple:
+    """Renvoie les coordonnées du premier nombre dans la matrice qui est plus grand que le nombre donné"""
+    for i in range(len(tab)):
+        for j in range(len(tab[i])):
+            if tab[i][j] >= nb:
+                return (i, j)
+
+
+
+
+## Fonctions de retraçage ##
+
 def retrace_image(chemin_img_source: str, nom_image_sortie: str, resize: bool = False):
 def retrace_image(chemin_img_source: str, nom_image_sortie: str, resize: bool = False):
     """Retrace l'image donnée avec des fils et sauvegarde dans le dossier resultat, au chemin donné"""
     """Retrace l'image donnée avec des fils et sauvegarde dans le dossier resultat, au chemin donné"""
     image = import_image(chemin_img_source, resize)
     image = import_image(chemin_img_source, resize)
@@ -409,6 +461,8 @@ def retrace_image_clous_aleatoires(chemin_img_source: str, nom_image_sortie: str
     image = import_image(chemin_img_source, resize)
     image = import_image(chemin_img_source, resize)
 
 
     new_img = tab_image_blanche(get_longueur_img(image), get_hauteur_img(image))
     new_img = tab_image_blanche(get_longueur_img(image), get_hauteur_img(image))
+    svg = dw.Drawing(get_longueur_img(image), get_hauteur_img(image))
+    svg.append(dw.Rectangle(x=0, y=0, width='100%', height='100%', fill='white'))
 
 
     clous = generer_clous_plus_clous_aleatoires(new_img)
     clous = generer_clous_plus_clous_aleatoires(new_img)
 
 
@@ -428,7 +482,7 @@ def retrace_image_clous_aleatoires(chemin_img_source: str, nom_image_sortie: str
             cpt_augmentation_err = 0
             cpt_augmentation_err = 0
 
 
         new_img = tracer_droite(clou_dep, meilleur_clou, new_img)
         new_img = tracer_droite(clou_dep, meilleur_clou, new_img)
-
+        svg.append(dw.Line(clou_dep[0], clou_dep[1], meilleur_clou[0], meilleur_clou[1], stroke='black', stroke_opacity=0.2, stroke_width=1))
 
 
         clou_dep = meilleur_clou
         clou_dep = meilleur_clou
         cpt_droites += 1
         cpt_droites += 1
@@ -437,14 +491,132 @@ def retrace_image_clous_aleatoires(chemin_img_source: str, nom_image_sortie: str
 
 
     image_res = Image.fromarray(uint8(new_img))
     image_res = Image.fromarray(uint8(new_img))
     image_res.save("resultat-clous-al/" + nom_image_sortie + ".png")
     image_res.save("resultat-clous-al/" + nom_image_sortie + ".png")
+    svg.save_svg("resultat-clous-al/" + nom_image_sortie + ".svg")
 
 
 
 
+def retrace_image_clous_aleatoires_b_sur_n(chemin_img_source: str, nom_image_sortie: str, resize: bool = False):
+    """Retrace l'image donnée avec des fils blancs sur fond noir et sauvegarde dans le dossier resultat, au chemin donné"""
+    image = import_image(chemin_img_source, resize)
 
 
-### Tests ###
+    new_img = tab_image_noire(get_longueur_img(image), get_hauteur_img(image))
+
+    clous = generer_clous_plus_clous_aleatoires(new_img)
+
+    clou_dep = clous[0]
+    cpt_augmentation_err = 0
+    cpt_droites = 0
+
+    while cpt_augmentation_err < 3:
+        meilleur_clou, reduction_err = trouve_meilleure_droite_blanche(image, new_img, clou_dep, clous)
+
+        print(reduction_err, clou_dep, meilleur_clou)
+
+        if reduction_err >= 0:
+            cpt_augmentation_err += 1
+        # On ne trace la droite que si elle réduit l'erreur
+        else:
+            cpt_augmentation_err = 0
+
+        new_img = tracer_droite_blanche(clou_dep, meilleur_clou, new_img)
+
+
+        clou_dep = meilleur_clou
+        cpt_droites += 1
+
+    print(cpt_droites)
+
+    image_res = Image.fromarray(uint8(new_img))
+    image_res.save("resultat-clous-al-bsn/" + nom_image_sortie + ".png")
+
+
+
+### Laplacien ###
+
+def retrace_avec_laplacien(chemin_img_source: str, nom_image_sortie: str, resize: bool = False):
+    """Retrace l'image donnée avec des fils en s'aidant d'un filtre laplacien et sauvegarde dans le dossier resultat, au chemin donné"""
+    image = import_image(chemin_img_source, resize)
+
+    new_img = tab_image_blanche(get_longueur_img(image), get_hauteur_img(image))
+    svg = dw.Drawing(get_longueur_img(image), get_hauteur_img(image))
+    svg.append(dw.Rectangle(x=0, y=0, width='100%', height='100%', fill='white'))
+
+    image_lap = import_image(chemin_img_source, resize, lap=True)   # On importe l'image en laplacien grâce à lap=True
 
 
-retrace_image_clous_aleatoires("images/chateau.jpg", "chateau-400px", True)
+    clous = generer_clous_lap(image_lap)
+
+    clou_dep = clous[0]
+    cpt_augmentation_err = 0
+    cpt_droites = 0
+
+    while cpt_augmentation_err < 3:
+        meilleur_clou, reduction_err = trouve_meilleure_droite(image, new_img, clou_dep, clous)
+
+        print(reduction_err, clou_dep, meilleur_clou)
+
+        if reduction_err >= 0:
+            cpt_augmentation_err += 1
+        # On ne trace la droite que si elle réduit l'erreur
+        else:
+            cpt_augmentation_err = 0
+
+        new_img = tracer_droite(clou_dep, meilleur_clou, new_img)
+        svg.append(dw.Line(clou_dep[0], clou_dep[1], meilleur_clou[0], meilleur_clou[1], stroke='black', stroke_opacity=0.2, stroke_width=1))
+
+        # Image.fromarray(uint8(new_img)).save("gif-pommes/" + str(cpt_droites).zfill(5) + ".png")
+
+        clou_dep = meilleur_clou
+        cpt_droites += 1
+
+    print(cpt_droites)
+
+    image_res = Image.fromarray(uint8(new_img))
+    image_res.save("resultat-laplacien/" + nom_image_sortie + ".png")
+    svg.save_svg("resultat-laplacien/" + nom_image_sortie + ".svg")
+
+
+def retrace_avec_laplacien_traits_blancs(chemin_img_source: str, nom_image_sortie: str, resize: bool = False):
+    """Retrace l'image donnée avec des fils blancs en s'aidant d'un filtre laplacien et sauvegarde dans le dossier resultat, au chemin donné"""
+    image = import_image(chemin_img_source, resize)
+
+    new_img = tab_image_noire(get_longueur_img(image), get_hauteur_img(image))
+    svg = dw.Drawing(get_longueur_img(image), get_hauteur_img(image))
+    svg.append(dw.Rectangle(x=0, y=0, width='100%', height='100%', fill='black'))
+
+    image_lap = import_image(chemin_img_source, resize, lap=True)   # On importe l'image en laplacien grâce à lap=True
+
+    clous = generer_clous_lap(image_lap)
+
+    clou_dep = clous[0]
+    cpt_augmentation_err = 0
+    cpt_droites = 0
+
+    while cpt_augmentation_err < 3:
+        meilleur_clou, reduction_err = trouve_meilleure_droite_blanche(image, new_img, clou_dep, clous)
+
+        print(reduction_err, clou_dep, meilleur_clou)
+
+        if reduction_err >= 0:
+            cpt_augmentation_err += 1
+        # On ne trace la droite que si elle réduit l'erreur
+        else:
+            cpt_augmentation_err = 0
+
+        new_img = tracer_droite_blanche(clou_dep, meilleur_clou, new_img)
+        svg.append(dw.Line(clou_dep[0], clou_dep[1], meilleur_clou[0], meilleur_clou[1], stroke='white', stroke_opacity=0.2, stroke_width=1))
+
+        # Image.fromarray(uint8(new_img)).save("gif-pommes/" + str(cpt_droites).zfill(5) + ".png")
+
+        clou_dep = meilleur_clou
+        cpt_droites += 1
+
+    print(cpt_droites)
+
+    image_res = Image.fromarray(uint8(new_img))
+    image_res.save("resultat-laplacien-bsn/" + nom_image_sortie + ".png")
+    svg.save_svg("resultat-laplacien-bsn/" + nom_image_sortie + ".svg")
+
+### Tests ###
 
 
+retrace_avec_laplacien_traits_blancs("images/hibou.jpg", "hibou-400px-600clous", True)
 
 
-### TODO ###
 
 
-# Pas forcément mesurer l'erreur d'une bande de quelques pixels au bord si on met les clous dedans