Forráskód Böngészése

ajout du traçage de droites

Ajout du calcul des points par lesquels le segment qui relie deux clous passe. Possibilité de tracer une droite avec la fonction tracer_droite(). Commentaires
Harupi 7 hónapja
szülő
commit
466bfc559b
1 módosított fájl, 122 hozzáadás és 26 törlés
  1. 122 26
      main.py

+ 122 - 26
main.py

@@ -1,15 +1,9 @@
+### Modules ###
+
 from PIL import Image
 from PIL import Image
 from numpy import asarray, ndarray, array, uint8, delete
 from numpy import asarray, ndarray, array, uint8, delete
 from random import choice
 from random import choice
 
 
-# image = Image.open("images/hibou.jpg")
-
-# image = image.convert("L")
-
-# img_array = asarray(image)
-
-# print(len(img_array[0])//3)
-
 
 
 ### Fonctions ###
 ### Fonctions ###
 
 
@@ -82,13 +76,13 @@ def generer_clous(tab_img: ndarray) -> list:
     l = get_longueur_img(tab_img)
     l = get_longueur_img(tab_img)
 
 
     for i in range(0, l, 10):
     for i in range(0, l, 10):
-        liste_res = liste_res + [(0, i, 0)]
+        liste_res = liste_res + [(i, 0, 0)]
     for i in range(10, h, 10):
     for i in range(10, h, 10):
-        liste_res = liste_res + [(i, l - 1, 1)]
-    for i in range(0, l - 10, 10):
-        liste_res = liste_res + [(h - 1, i, 2)]
-    for i in range(10, h - 10, 10):
-        liste_res = liste_res + [(i, 0, 3)]
+        liste_res = liste_res + [(l - 1, i, 1)]
+    for i in range(l - 11, -1, - 10):
+        liste_res = liste_res + [(i, h - 1, 2)]
+    for i in range(h - 11, 0, -10):
+        liste_res = liste_res + [(0, i, 3)]
 
 
     return liste_res
     return liste_res
 
 
@@ -100,13 +94,102 @@ def clou_choisi_al(liste_clous : list) -> tuple:
     """On choisie un clou aléatoirement"""
     """On choisie un clou aléatoirement"""
     return random.choice(liste_clous)
     return random.choice(liste_clous)
 
 
-def tracer_droite(clou1: tuple, clou2: tuple, image: list) -> list:
+def tracer_droite(clou1: tuple, clou2: tuple, image: ndarray) -> ndarray:
     """Trace une droite d'un clou à un autre."""
     """Trace une droite d'un clou à un autre."""
-    if clou2[3]==clou1[3]:
-        print("il est impossible de tracer un trait sur le même bord")
+    if visible(clou1, clou2):
+        liste_points = liste_points_traverses(clou1, clou2, image)
+        
+        for i in range(0, len(liste_points)):
+            ligne = liste_points[i][1]
+            col = liste_points[i][0]
+            image = assombrir_pixel(image, ligne, col)
     else:
     else:
+        print("il est impossible de tracer un trait sur le même bord")
+
+    return image
+
+def liste_points_traverses(clou1: tuple, clou2: tuple, image: ndarray) -> list:
+    """Renvoie les points traversés par le segment [coul1, clou2] traverse"""
+    liste_res = []
+    liste_motif = liste_points_traverses_par_motif(clou1, clou2, image)
+
+    l = get_longueur_img(image)
+    h = get_hauteur_img(image)
+
+    x1 = clou1[0]
+    x2 = clou2[0]
+    y1 = clou1[1]
+    y2 = clou2[1]
+
+    # On inverse l'ordre des clous si besoin, ça pourrait être fait de façon plus propre
+    if x1 > x2:
+        clou1, clou2, x1, x2, y1, y2 = clou2, clou1, x2, x1, y2, y1
+    elif x1 == x2:
+        if y1 > y2:
+            clou1, clou2, x1, x2, y1, y2 = clou2, clou1, x2, x1, y2, y1
+
+    # On applique le motif depuis le point de départ, et on ajoute les points obtenus dans la liste si ils rentrent dans l'image
+    for i in range(0, len(liste_motif)):
+            if (liste_motif[i][0] + x1 < l) and (0 <= liste_motif[i][1] + y1) and (liste_motif[i][1] + y1 < h):
+                liste_res = liste_res + [(liste_motif[i][0] + x1, liste_motif[i][1] + y1)]
         
         
-        pass
+    return liste_res
+
+
+def liste_points_traverses_par_motif(clou1: tuple, clou2: tuple, image: ndarray) -> list:
+    """Renvoie la liste des points que le motif de la doite passant par clou1 et clou2 traverse"""
+    liste_res = []
+
+    l = get_longueur_img(image)
+    h = get_hauteur_img(image)
+
+    x1 = clou1[0]
+    x2 = clou2[0]
+
+    # On échange les clous si besoin, pourrait toujours être fait plus proprement
+    if x1 > x2:
+        clou1, clou2 = clou2, clou1
+    # Gestion des droites verticales
+    elif x1 == x2:
+        liste_res = [(0, i) for i in range(0, h)]
+
+    a, b = calcul_droite(clou1, clou2)
+
+    y1 = clou1[1]
+    y2 = clou2[1]
+
+    mu = 0
+
+    # Si la droite "descend"
+    if y1 < y2:
+        # On teste tous les pixels, ça peut être grandement optimisé
+        for x in range(0, l):
+            for y in range(0, h):
+                # On calcule un "reste" (ax + by) qui lorsqu'il se trouve entre mu et mu + max(a, b) permet de créer un motif. On dessine ici le motif à partir de l'origine
+                if (mu <= a * x + b * y) and (a * x + b * y < mu + max(a, b)):
+                    liste_res = liste_res + [(x, y)]
+
+    # Si la droite "monte"
+    else:
+        for x in range(0, l):
+            for y in range(0, h):
+                # Pareil qu'au dessus, sauf que le reste vaut (ax - by) et qu'on trace le motif à partir du point en bas à gauche
+                if (mu <= a * x - b * y) and (a * x - b * y < mu + max(a,  b)):
+                    liste_res = liste_res + [(x, - y)]
+
+    return liste_res
+
+def calcul_droite(clou1: tuple, clou2: tuple) -> tuple:
+    """Renvoie les coordonnées du vecteur orthogonal au vecteur allant de clou1 à clou2"""
+    x1 = clou1[0]
+    x2 = clou2[0]
+    y1 = clou1[1]
+    y2 = clou2[1]
+
+    a = y1 - y2
+    b = x2 - x1    
+
+    return (a, b)
 
 
 def lst_zone(image) -> list:
 def lst_zone(image) -> list:
     """Renvoie une liste avec les coordonées de chaques zones"""
     """Renvoie une liste avec les coordonées de chaques zones"""
@@ -116,7 +199,7 @@ def lst_zone(image) -> list:
     pas = 10
     pas = 10
     for i in range(0,longueur,pas):
     for i in range(0,longueur,pas):
         for j in range(0,hauteur, pas):
         for j in range(0,hauteur, pas):
-            lst += [(i,j)] #prends les coordonnées du pixel en haut à gauche de chaque zone
+            lst += [(i,j)] # prends les coordonnées du pixel en haut à gauche de chaque zone
     return lst  
     return lst  
 
 
 def erreur_moyenne_zone(image1, image2, zone : tuple, longueur : int)  -> float:
 def erreur_moyenne_zone(image1, image2, zone : tuple, longueur : int)  -> float:
@@ -144,15 +227,21 @@ def erreur(image1, image2, zones : list) -> float:
         moy += erreur_moyenne_zone(image1, image2,zones[i])
         moy += erreur_moyenne_zone(image1, image2,zones[i])
     return moy/len(zones)
     return moy/len(zones)
 
 
+
+
+
+
+### Tests (à nettoyer) ###
+
 image = import_image("images/hibou.jpg")
 image = import_image("images/hibou.jpg")
-print(image)
+# print(image)
+# print(len(image))
+# print(len(image[0]))
 
 
 image_blanche = tab_image_blanche(get_longueur_img(image), get_hauteur_img(image))
 image_blanche = tab_image_blanche(get_longueur_img(image), get_hauteur_img(image))
 
 
 image_noir = tab_image_noir(get_longueur_img(image), get_hauteur_img(image))
 image_noir = tab_image_noir(get_longueur_img(image), get_hauteur_img(image))
 
 
-print(image_blanche)
-
 img = Image.fromarray(uint8(image_blanche))
 img = Image.fromarray(uint8(image_blanche))
 
 
 for i in range(0, 50):
 for i in range(0, 50):
@@ -162,20 +251,27 @@ for i in range(0, 50):
 img = Image.fromarray(uint8(image_blanche))
 img = Image.fromarray(uint8(image_blanche))
 #img.show()
 #img.show()
 
 
-print(image_blanche)
+#print(image_blanche)
 
 
 clous = generer_clous(image_blanche)
 clous = generer_clous(image_blanche)
-print(clous)
+#print(clous)
 
 
-test = tab_image_blanche(111, 111)
+test = tab_image_blanche(1000, 1000)
 c = generer_clous(test)
 c = generer_clous(test)
+
 for i in range(0, len(c)):
 for i in range(0, len(c)):
     test = assombrir_pixel(test, c[i][0], c[i][1])
     test = assombrir_pixel(test, c[i][0], c[i][1])
+test = tracer_droite(c[35], c[321], test)
+
 im_test = Image.fromarray(uint8(test))
 im_test = Image.fromarray(uint8(test))
 im_test.show()
 im_test.show()
 
 
 l_zones = lst_zone(image)
 l_zones = lst_zone(image)
-print(erreur_moyenne_zone(image, image_blanche,l_zones[500],10))
+# print(erreur_moyenne_zone(image, image_blanche,l_zones[500],10))
+
+
+
+
 ### TODO ###
 ### TODO ###
 
 
 # On peut essayer de regarder des clous aléatoire plutôt que de tout tester
 # On peut essayer de regarder des clous aléatoire plutôt que de tout tester