Partage
  • Partager sur Facebook
  • Partager sur Twitter

Réaliser un "quadrillage"

    15 février 2016 à 16:41:11

    Bonjour,

    Le but de mon programme étant, à partir d'une image en noir/blanc, de relever les pixels les plus foncés dans divers emplacement de l'image.
    J'ai dans un premier temps fait quelque chose qui me permet d'obtenir les pixels les plus foncés de chaque ligne. 

    import matplotlib.pyplot as plt
    import matplotlib.image as mim
     
    monimage=mim.imread('a.png')
     
    def empreinte(monimage):
        l,c=monimage.shape[0],monimage.shape[1]
        L=[]
        for i in range(l):
            a=(monimage[:,:,0][i])
    #a est donc la liste correspond à la couleur des pixels de la ligne i
            L.append(np.argmin(a))
        X=[j for j in range (l)]
        print (L)
        plt.scatter(L,X)
        plt.show()

    Etant débutant j'imagine qu'il est loin d'être épuré, si vous avez des suggestions pour améliorer sa lisibilité je suis pas contre.


    Néanmoins, je cherche maintenant à faire la même chose, pas sur juste chaque ligne, mais sur un domaine d'un quadrillage. En gros, je cherche à diviser une image de départ en n*m petits images carrés et de ne relever le pixel le plus foncé que dans chacun de ses petits images. A part créer le quadrillage "à la main" à l'aide de boucles et en mettant les points d'un même domaine dans une même liste pour pouvoir y appliquer la fonction précédente et enfin réarranger les indices, je ne vois pas comment je pourrais faire ça, surtout que ça va faire beaucoup de lignes pour rien. Auriez-vous une idée, une piste vers une meilleure solution ?

    • Partager sur Facebook
    • Partager sur Twitter
      16 février 2016 à 17:18:43

      Quelque chose comme ça ?

      import urllib2
      import matplotlib.pyplot as plt
      import matplotlib.image as mim
      import numpy as np
      
      def reformat_picture_matrix(picture) :
          return np.array([[values[0] for values in row] for row in picture])
      
      def empreinte(picture, col_size=None, row_size=None) :
          matrix = reformat_picture_matrix(picture)
      
          matrix_shape = matrix.shape
          if not col_size : col_size = matrix_shape[1]
          if not row_size : row_size = matrix_shape[0]
          data_point = []
      
          for i in range(0, matrix_shape[0], row_size) :
              for j in range(0, matrix_shape[1], col_size) :
                  submatrix = matrix[i:i+row_size,j:j+col_size]
                  min_idx = np.argmin(submatrix)
                  row = i + min_idx / col_size
                  col = j + min_idx % col_size
                  data_point.append((col, row))
      
          plt.scatter(*zip(*data_point), color="black")
          plt.show()
      
      url = "http://matplotlib.org/_images/stinkbug.png"
      picture = urllib2.urlopen(url)
      picture = mim.imread(picture)
      empreinte(picture, 1, None) # each row
      empreinte(picture, None, 1) # each col
      empreinte(picture, 10, 10) # each 10x10 squares

      Je ne suis pas sûr du résultat mais ça m'a l'air bon ! Par contre on est d'accord que ça ne fonctionne que pour des images en N&B.

      • Partager sur Facebook
      • Partager sur Twitter
        17 février 2016 à 8:44:11

        Jevanni a écrit:

        Quelque chose comme ça ?

        import urllib2
        import matplotlib.pyplot as plt
        import matplotlib.image as mim
        import numpy as np
        
        def reformat_picture_matrix(picture) :
            return np.array([[values[0] for values in row] for row in picture])
        
        def empreinte(picture, col_size=None, row_size=None) :
            matrix = reformat_picture_matrix(picture)
        
            matrix_shape = matrix.shape
            if not col_size : col_size = matrix_shape[1]
            if not row_size : row_size = matrix_shape[0]
            data_point = []
        
            for i in range(0, matrix_shape[0], row_size) :
                for j in range(0, matrix_shape[1], col_size) :
                    submatrix = matrix[i:i+row_size,j:j+col_size]
                    min_idx = np.argmin(submatrix)
                    row = i + min_idx / col_size
                    col = j + min_idx % col_size
                    data_point.append((col, row))
        
            plt.scatter(*zip(*data_point), color="black")
            plt.show()
        
        url = "http://matplotlib.org/_images/stinkbug.png"
        picture = urllib2.urlopen(url)
        picture = mim.imread(picture)
        empreinte(picture, 1, None) # each row
        empreinte(picture, None, 1) # each col
        empreinte(picture, 10, 10) # each 10x10 squares

        Je ne suis pas sûr du résultat mais ça m'a l'air bon ! Par contre on est d'accord que ça ne fonctionne que pour des images en N&B.

        Bonjour, merci pour ton aide avant tout.

        Je n'ai pas testé avec toutes sortes d'images N/B que j'ai à ma disposition, mais sur les quelques simples que j'ai, ça a l'air d'être parfaitement ce que je recherche.

        Par contre je n'ai pas très bien compris quelques parties du code (je suis encore un novice !). 

        def reformat_picture_matrix(picture) :
            return np.array([[values[0] for values in row] for row in picture])

        Si j'ai bien compris la fonction renvoie un tableau array à partir d'une image. Mais qu'est-ce exactement row ? La matrice des constituant de chaque pixel (R,G,B) ? 

        Sinon pour  la ligne 21 - 22

        row = i + min_idx / col_size
        col = j + min_idx % col_size

        Le i et le j à gauche de chaque + c'est bien pour redonner les bonnes indices par rapport à la matrice originale et pas la sous-matrice ? min_idx étant le couple d'indice du minimum dans la sous-matrice ?

        Pourquoi diviser et prendre le reste par col_size ?

        Et enfin dans

        plt.scatter(*zip(*data_point), color="black")

        Que permet 

        *zip(*

        Encore merci ! 

        -
        Edité par Shazaam 17 février 2016 à 8:55:20

        • Partager sur Facebook
        • Partager sur Twitter
          17 février 2016 à 13:41:52

          Salut, pas de problèmes. Pour les explications :

          Ligne 7 : Cette fonction a pour simple but de rendre la matrice plus facile à analyser. Quand tu regardes le résultat (comme le point 4 ici) de imread, ton image est en fait une matrice à deux dimensions ou chaque case représente un pixel, un pixel étant lui même une liste de 3 valeurs correspondant au RGB. Comme tes images sont en N&B, les valeurs de RGB sont identiques pour chaque pixel. Du coup l'idée ici est de reconstituer la matrice de ton image, mais au lieu d'avoir une liste de RGB pour chaque pixel, tu n'as qu'une valeur. D'un point de vue du code, tu peux réécrire ça de cette manière :

          def reformat_picture_matrix_2(picture) :
              new_matrix = []
              
              for row in picture :
                  new_row = []
                  for pixel in row :
                      new_row.append(pixel[0])
                  new_matrix.append(new_row)
          
              new_array = np.array(new_matrix)
              return new_array

          Ligne 21-22 : Il faut voir comme se comporte np.argmin() avec une matrice à deux dimensions pour comprendre. Si on prend deux exemples :

          import numpy as np
          
          matrice = np.array([[6,0,3],[2,2,4]])
          print np.argmin(matrice), np.argmin(matrice)/3, np.argmin(matrice)%3
          
          # 1 0 1
          
          matrice = np.array([[6,3,3],[3,2,4]])
          print np.argmin(matrice), np.argmin(matrice)/3, np.argmin(matrice)%3
          
          # 4 1 1

          Quand tu as plusieurs lignes dans ta matrice, np.argmin te donne (si tu ne lui précises pas d'axes en argument), l'index comme si tu avais coller l'ensemble de tes listes en une seule liste. Du coup le moyen simple de retrouve la ligne et la colonne et de diviser l'index donné par le nombre de colonnes dans ta matrice (indiqué dans le code comme col_size), l'opérateur / te donne le quotient (la ligne) et % te donne le reste (la colonne). i et j permettent effectivement de donner la position par rapport à l'ensemble de la matrice.

          Et enfin pour * : C'est ce que l'on appelle l'opérateur splat en python, et te permet, entre autre, de faire passer les éléments d'une liste directement en argument pour une fonction. Je te conseille de lire cet article si ça t'intéresse. Après c'est pas LE truc à connaître quand tu débutes en python. C'est juste une habitude au bout d'un moment d'utiliser ce genre de raccourcis.

          • Partager sur Facebook
          • Partager sur Twitter
            18 février 2016 à 17:40:08

            Jevanni a écrit:

            Salut, pas de problèmes. Pour les explications :

            Ligne 7 : Cette fonction a pour simple but de rendre la matrice plus facile à analyser. Quand tu regardes le résultat (comme le point 4 ici) de imread, ton image est en fait une matrice à deux dimensions ou chaque case représente un pixel, un pixel étant lui même une liste de 3 valeurs correspondant au RGB. Comme tes images sont en N&B, les valeurs de RGB sont identiques pour chaque pixel. Du coup l'idée ici est de reconstituer la matrice de ton image, mais au lieu d'avoir une liste de RGB pour chaque pixel, tu n'as qu'une valeur. D'un point de vue du code, tu peux réécrire ça de cette manière :

            def reformat_picture_matrix_2(picture) :
                new_matrix = []
                
                for row in picture :
                    new_row = []
                    for pixel in row :
                        new_row.append(pixel[0])
                    new_matrix.append(new_row)
            
                new_array = np.array(new_matrix)
                return new_array

            Ligne 21-22 : Il faut voir comme se comporte np.argmin() avec une matrice à deux dimensions pour comprendre. Si on prend deux exemples :

            import numpy as np
            
            matrice = np.array([[6,0,3],[2,2,4]])
            print np.argmin(matrice), np.argmin(matrice)/3, np.argmin(matrice)%3
            
            # 1 0 1
            
            matrice = np.array([[6,3,3],[3,2,4]])
            print np.argmin(matrice), np.argmin(matrice)/3, np.argmin(matrice)%3
            
            # 4 1 1

            Quand tu as plusieurs lignes dans ta matrice, np.argmin te donne (si tu ne lui précises pas d'axes en argument), l'index comme si tu avais coller l'ensemble de tes listes en une seule liste. Du coup le moyen simple de retrouve la ligne et la colonne et de diviser l'index donné par le nombre de colonnes dans ta matrice (indiqué dans le code comme col_size), l'opérateur / te donne le quotient (la ligne) et % te donne le reste (la colonne). i et j permettent effectivement de donner la position par rapport à l'ensemble de la matrice.

            Et enfin pour * : C'est ce que l'on appelle l'opérateur splat en python, et te permet, entre autre, de faire passer les éléments d'une liste directement en argument pour une fonction. Je te conseille de lire cet article si ça t'intéresse. Après c'est pas LE truc à connaître quand tu débutes en python. C'est juste une habitude au bout d'un moment d'utiliser ce genre de raccourcis.


            Merci pour ces explications claires et précises !
            • Partager sur Facebook
            • Partager sur Twitter
              18 février 2016 à 18:04:20

              @Shazaam: juste une petite remarque (sans méchanceté): pas la peine de citer à chaque fois la personne (ça alourdit inutilement la discussion). Surtout quand le message n'est pas très loin ;).
              • Partager sur Facebook
              • Partager sur Twitter
              Précepte: Le mieux est l'ennemi du bien

              Réaliser un "quadrillage"

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown