1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut gestion des pixels d'une image par python.

    Bonjour ,

    Connaitrez-vous la manière dont python gère les images au niveau du pixels? Comme copiez un bout d'une image dans une variable ou comparer deux images pour voir si elles sont identiquent?

    Je voudrais pouvoir découper une image en bloc et ensuite comparer ces blocs les un, les autre pour éviter les bloc identiques. Je pourrais ensuite les regrouper et en faire un tilesheet.

    Bonne journées,

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : juin 2009
    Messages : 447
    Points : 751
    Points
    751

    Par défaut

    Dans l'absolu ça dépend du module que tu utilises pour la gestion d'image.
    Si tu usilises numpy/scipy, il s'agit de simples tableaux à 2 (niveaux de gris) ou 3 (couleur) dimensions. Et il suffit d'utiliser des "slices" pour acceder à une sous partie (block) de l'image.

    pour info les fonction pour lire/écrire/afficher les images sont dans scipy.misc

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut

    A merci, je vais regarder ça. En cherchant je suis tombé sur pythonware je sais pas si ça se vaut?

  4. #4
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : juin 2009
    Messages : 447
    Points : 751
    Points
    751

    Par défaut

    la PIL (python image library) est pratique notamment si tu veux dessiner dans ton image. Pour la manipulation directe de pixels, je préfère nettement l'utilisation de tableau numpy, ce qui permet de vectoriser les opération (tu evites les boucles imbriquées qui peuvent être très lente en python).

    Au passage tu peux passer de l'un à l'autre grâce aux fonctions fromimage et toimage de scipy.misc.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut

    Comment se fait l’installation de la partie scipy.

    je ai récupéré la dernière version sur sourceforge :

    http://sourceforge.net/projects/scipy/files/


    j'ai téléchargé le zip, mais je vois pas ou l’installer, même en le dézipant on n'obtient pas d’exécutable. Je n'ai pas trouvé la version avec laquelle il est compatible.

  6. #6
    Membre éclairé
    Homme Profil pro
    Ingénieur R&D en apprentissage statistique
    Inscrit en
    juin 2009
    Messages
    447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur R&D en apprentissage statistique

    Informations forums :
    Inscription : juin 2009
    Messages : 447
    Points : 751
    Points
    751

    Par défaut

    En général, il y a un fichier setup.py. Pour compiler et installer tu peux faire:

    $ python setup.py install [--prefix=some_non_default_path]
    (les [] indique que c'est optionnel)

    cela nécessite que les distutils soient installés mais il me semble que c'est standard.

    Sinon, si tu as easy_install ou pip d'installé:
    $ easy_install [--prefix=some_path] scipy
    Il devrait faire les vérifications de dépendance, le téléchargement de la version compatible, sa compilation et son installation.

    Après j'imagine que tu es sous Windows ou Mac (sous Linux il suffit de choisir les paquets à installer), et je n'ai aucune expérience de l'installation sous ces systèmes

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut

    En fait, il y a un .exe, mai il faut aller dans les dossier et pas s’arrêter au téléchargement proposé. Par contre j'ai pas retrouvé ou il était pour metre le lien au cas ou .

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    juillet 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2012
    Messages : 2
    Points : 2
    Points
    2

    Par défaut

    Citation Envoyé par Alexis.M Voir le message
    la PIL (python image library) est pratique notamment si tu veux dessiner dans ton image. Pour la manipulation directe de pixels, je préfère nettement l'utilisation de tableau numpy, ce qui permet de vectoriser les opération (tu evites les boucles imbriquées qui peuvent être très lente en python).

    Au passage tu peux passer de l'un à l'autre grâce aux fonctions fromimage et toimage de scipy.misc.
    Est-il possible d'expliciter ce que signifie "vectoriser" ? Avec un exemple simple ?
    J'ai dans l'idée que c'est un reshape d'une matrice pour en faire une matrice avec une seule ligne.

    Est-ce exact ?

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : mars 2007
    Messages : 941
    Points : 1 379
    Points
    1 379

    Par défaut

    Citation Envoyé par lamingue Voir le message
    Est-il possible d'expliciter ce que signifie "vectoriser" ? Avec un exemple simple ?
    J'ai dans l'idée que c'est un reshape d'une matrice pour en faire une matrice avec une seule ligne.

    Est-ce exact ?
    Vectoriser, c'est éviter les boucles explicites, en utilisant des opérations qui traitent directement des tableaux/matrices.

    par exemple, voici 2 matrices de dimension 2x2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> from numpy import *
    >>> A = array([[1,2],[3,4]])
    >>> B = array([[3,4],[5,6]])
    pour additionner les éléments de A et B, on pourrait écrire, sans vectoriser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> C = empty_like(A)
    >>> for i in range(C.shape[0]):
    ... 	for j in range(C.shape[1]):
    ... 		C[i,j] = A[i,j] + B[i,j]
    Avec vectorisation:
    Cela va plus loin que les "simples" opérations matricielles; on a aussi le "broadcasting", qui permet d'appliquer des opérations à des tableaux de taille différentes (sous certaines conditions de compatibilité).

    Par exemple, pour multiplier tous les éléments de A par 2, on peut écrire:
    2 est un scalaire, mais il peut être considéré comme une matrice avec une ligne et une colonne, qui est agrandie par duplication à la taille de A, et la division procède élément par élément (c'est le principe; c'est certainement plus optimisé que cela).

    Si maintenant je veux multiplier la première colonne par 2 et la seconde par 3:
    Ou bien la première ligne par 2 et la seconde par 3:

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut

    A oui, merci pour l'explication, j'étais partie sur toute autre chose pour les notions de vectoriel.

    Mais du coup si on veut voir si deux images sont identiques il suffit de faire

    C=A-B

    si C renvoie NONE les deux images le sont?

    Je demande ça car j'ai trouvé différente ma,ière de tester l'égalité.
    numpy.array_equiv ,numpy.array_equal même (A==B).all().

    j'ai testé les deux premières et je me demande pourquoi il y a deux fonctions pour faire la même chose et je vois pas la différence. Est ce due a une évolution du module?

  11. #11
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : mars 2007
    Messages : 941
    Points : 1 379
    Points
    1 379

    Par défaut

    Citation Envoyé par pierre-y Voir le message
    Mais du coup si on veut voir si deux images sont identiques il suffit de faire

    C=A-B

    si C renvoie NONE les deux images le sont?
    C sera un tableau de la même taille que A et B, dont chaque élément sera la différence entre les éléments de même position dans A et B. Donc, si A et B sont égaux, C sera un tableau qui ne contient que des zéros.

    Je demande ça car j'ai trouvé différente ma,ière de tester l'égalité.
    numpy.array_equiv ,numpy.array_equal même (A==B).all().

    j'ai testé les deux premières et je me demande pourquoi il y a deux fonctions pour faire la même chose et je vois pas la différence. Est ce due a une évolution du module?
    array_equal vérifie que les deux tableaux sont de mêmes dimensions et que leur éléments sont égaux.
    array_equiv, c'est presque la même chose, mais les deux tableaux doivent seulement être compatibles du point de vue du broadcasting, ils ne doivent pas avoir exactement la même taille.
    (A==B).all() est équivalent à array_equiv(A,B); il construit d'abord une matrice de booléens et vérifie ensuite qu'ils sont tous True.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    >>> from numpy import *
    >>> A = array([[2,2]])      # dimension = 1 x 2
    >>> B = array([[2],
    ...            [2]])        # dimension = 2 x 1
    >>> array_equal(A,B)
    False
    >>> array_equiv(A,B)
    True
    >>> A==B
    array([[ True,  True],
           [ True,  True]], dtype=bool)   # car (1 x 2) et (2 x 1) sont broadcastés à une forme compatible (2 x 2)
    >>> (A==B).all()
    True
    >>> A - B
    array([[0, 0],
           [0, 0]])
    >>> not (A - B).any()      # encore une autre façon
    True

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut

    Bonjour,

    Est ce que le vectoriel permet de gérer la placement d'un tableau dans un autre et de gérer un éventuelle débordement? ou alors, a se moment la, le passage par un bouclage est-il obligatoire?

    Un schéma sera plus parlant je pense.

    un tableau de remplie de zero :

    0,0,0,0,0
    0,0,0,0,0
    0,0,0,0,0
    0,0,0,0,0
    0,0,0,0,0

    le tableau a intégrer :

    1,2,3
    4,5,6

    Est-il possible de placer un tableau en ciblant une position donné, ici une copie du tableau a partir de la position 2,2

    0,0,0,0,0
    0,0,0,0,0
    0,0,1,2,3
    0,0,4,5,6
    0,0,0,0,0

    ou de palier a un débordement du tableau :

    0,0,0,0,0
    0,0,0,0,0
    0,0,0,0,0
    0,0,0,1,2,3
    0,0,0,4,5,6

    pour obtenir ça :

    0,0,0,0,0
    0,0,0,0,0
    0,0,0,0,0
    0,0,0,1,2
    0,0,0,4,5

    Je pense que ça sera plus clair comme ça.

    bonne journée

  13. #13
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : mars 2007
    Messages : 941
    Points : 1 379
    Points
    1 379

    Par défaut

    On peut utiliser l'assignation par slices:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> t = zeros((5,5))
    >>> v = array([[1,2,3],[4,5,6]])
    >>> t[2:4,2:5] = v
    >>> t
    array([[ 0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  1.,  2.,  3.],
           [ 0.,  0.,  4.,  5.,  6.],
           [ 0.,  0.,  0.,  0.,  0.]])
    Maintenant, pour un placement arbitraire avec gestion de débordements, il faudra jouer avec des min/max pour déterminer le bon découpage de chaque tableau, mais ça tu devrais le faire aussi avec des boucles explicites.

    Si je ne me suis pas trompé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def place(t1, t2, (l,c)):
        l1 = max(0, l)
        c1 = max(0, c)
        l2 = max(0, -l)
        c2 = max(0, -c)
        h1, w1 = t1.shape
        h2, w2 = t2.shape
        w = max(0, min(w2-c2, w1-c1))
        h = max(0, min(h2-l2, h1-l1))
        t1[l1:l1+h, c1:c1+w] = t2[l2:l2+h, c2:c2+w]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    >>> t = zeros((5,5), dtype=int)
    >>> v = array([[1,2,3],[4,5,6]])
    >>> place(t, v, (2,3))
    >>> t
    array([[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [0, 0, 0, 1, 2],
           [0, 0, 0, 4, 5],
           [0, 0, 0, 0, 0]])
    >>> place(t, v, (1,-1))
    >>> t
    array([[0, 0, 0, 0, 0],
           [2, 3, 0, 0, 0],
           [5, 6, 0, 1, 2],
           [0, 0, 0, 4, 5],
           [0, 0, 0, 0, 0]])
    Si quelqu'un a plus simple, il est le bienvenu...

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut

    J'aurais une question sur la création de tableau.

    Peut on crée un tableau avec les même canots qu'une images ciblé mais pas forcement avec les même dimensions et sans connaitre a l'avance le type de l'image (rgb, monochrome,...)? par exemple avec une image de 40*50 disons une rgb avec alpha soit a 4 canots, créer un tableau de 80*100 qui pourra recevoir les info de cette image sans déperditions des infos.

    j'espère avoir été claire.

    bonne soirée ,

  15. #15
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : mars 2007
    Messages : 941
    Points : 1 379
    Points
    1 379

    Par défaut

    Je ne suis pas sûr d'avoir compris. Tu crées ton tableau au moment où tu en as besoin, à la taille dont tu as besoin.

    Et je ne comprends pas vraiment ton exemple; si tu as une image en RGBA (4 canaux), et que tu désires séparer les canaux, tu peux faire un tableau à 3 dimensions: 40x50x4. 160x100, ça fonctionne aussi, je suppose que tu penses à faire des blocs de 2x2 pour chaque pixel, mais ça me semble plus compliqué.

    Tu as choisi d'utiliser quoi exactement pour lire les images ?

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    décembre 2007
    Messages
    266
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2007
    Messages : 266
    Points : 485
    Points
    485

    Par défaut

    Pardon pour le temps de réponse, je cherchais un moyen plus clair d’expliquer mon problème. Pour le moment j'utilise le module tkFileDialog et Image pour charger mes images.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    self.refTILESET=tkFileDialog.askopenfilename(filetypes=[("Image Files", ("*.png","*.jpg", "*.gif")),("PNG",'*.png'),("JPEG",'*.jpg'),("GIF",'*.gif')])
     
    bitmap=Image.open(self.refTILESET)
    bmpData=bitmap.getdata()
    bmpTab=numpy.array(bmpData)
    Le mieux est peut être de commencer par le début.
    A la base, mon programme est assez simple. Il découpe un image en blocs égaux, les comparent et ne garde que ceux qui son différent, les regroupes et en fait un bitmap unique (qui n'a pas forcement la même taille que l'image) ; il crée aussi un csv pour pouvoir les replacer. J'ai lancé ça car j'avais besoin de se type d'outil pour faire de petit jeux a base de tile. Ça m'a semblé un bonne exercice pour apprendre python. J'ai découvert numpy après et j'aimerais bien continuer par la suite a l'utiliser pour m'entrainer encore en essayant de traiter des images.

    Mon problème se pose en deux endroits. Je crée a un moment donné un buffer dans lequel je vais coller des blocs d'une même images et aussi de la même façon lorsque je veux regrouper les bloc de l'images en un seul éléments.

    Comment crée un tableau de taille variable qui puisse contenir les même donnée qu'une image cible. Que par la suite je puisse traiter et sauvegarder sous le même formats que l'image de départ?

    J'espère avoir été plus claire.

  17. #17
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : mars 2007
    Messages : 941
    Points : 1 379
    Points
    1 379

    Par défaut

    Je comprends un peu mieux. Je vois deux possibilités:
    1. tu alloues un tableau assez grand pour le pire des cas (c'est à dire, aussi grand que ton bitmap de départ), et à la fin, quand tu connais la taille exacte, tu le découpes pour ne garder que la partie utile
    2. on ne peut pas directement agrandir un tableau, mais on peut "coller" ensemble des morceaux de tableaux (avec des fonctions comme hstack ou vstack dans numpy)


    Remarque qu'avec PIL, tu peux construire ton tableau plus facilement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bitmap=Image.open(self.refTILESET)
    bmpTab=numpy.array(bitmap)
    Si tu veux ajouter un bloc (une tile) dans un tableau résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    th, tw = 32,32 # taille d'une tile
    res = numpy.empty((0, tw) + bmpTab.shape[2:]) # tableau vide mais de dimensions compatibles
    ...
        # copier une tile en position (i,j):
        res = numpy.vstack((res, bmpTab[i*th:(i+1)*th, j*tw:(j+1)*tw]))
    ...
    A la fin, tu vas te retrouver avec tous les tiles en une colonne, mais un simple appel à reshape devrait te permettre de le rendre un peu plus "carré" si tu le désires.

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/03/2007, 16h39
  2. [FLASH 8] BitmapData -> changer des pixels d'une image en alpha
    Par Lorenzo77 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 4
    Dernier message: 15/12/2006, 18h13
  3. [c++.Net] Parcours des pixels d'une image
    Par CaptainChoc dans le forum Framework .NET
    Réponses: 4
    Dernier message: 27/11/2006, 17h05
  4. diffusion des pixels d'une image
    Par hagui dans le forum Traitement d'images
    Réponses: 11
    Dernier message: 11/05/2006, 19h31
  5. [MFC]déplacement des pixels d'une image
    Par hagui dans le forum MFC
    Réponses: 8
    Dernier message: 19/01/2006, 17h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo