IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Comparer deux images png


Sujet :

Python

  1. #1
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut Comparer deux images png
    Bonjour,

    J'aurais besoin de réaliser un programme pour valider certaines images png.

    Je m'explique : A partir d'une image modèle (de taille raisonnable en nombre de pixels), je voudrais vérifier que la deuxième image conserve bien la même position et la même couleur sur certains pixels.

    Mon idée serait de "scanner" l'image modèle, de récupérer les positions et couleurs de tous les pixels (après avoir filtré certains pixels qui ne m'intéresse pas comme les blancs par exemple) et de vérifier que dans la deuxième image on retrouve bien la position et la couleur de ces pixels.

    Est-ce faisable en Python ?

    J'ai bien vaguement tâté le terrain en recherchant certaines bibliothèques ou fonctions mais je m'y perds.

    Merci de votre aide.

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    je saurai faire ça avec pygame, mais il y a d'autres libs ...

  3. #3
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Bonjour,

    tu as tout ce qu'il te faut dans PIL (Python Imaging Library)

  4. #4
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut
    Merci pour la piste mais il semblerait que la version de PIL proposée ne fonctionne pas sur une version supérieur à la version 2.7 de Python...
    Je me trompe ?

    Si vous avez une idée de comment vous feriez vous pour arriver à ce résultat, n'hésitez pas... Je suis preneur à toute possiblité ou méthodologie différente pouvant m'amener au résultat escompté.

    Merci d'avance.

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 080
    Par défaut
    Bonjour,

    Votre recherche n'a pas dû aller très loin, voyez ici, bonne continuation...

  6. #6
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut
    Bonjour,

    Ah non effectivement, en regardant vite fait du boulot, je me suis fait piéger par la phrase du précédent lien : "A version for 3.X will be released later."

    Merci pour ce lien. Je vais voir ce que je peux trouver dans cette library.

  7. #7
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Question: Est-ce que seuls certains pixels doivent être identiques et que les autres seront différents ou bien les deux images doivent être identiques ?

    Dans ce dernier cas il suffit de comparer leur historique.

    Historique que PIL fait trè simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    img = Image.open(path)
    histo = img.histogram()

  8. #8
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Citation Envoyé par VinsS
    Dans ce dernier cas il suffit de comparer leur historique.
    ouh là ! même si les explications ne sont pas totalement précises, dans n'importe quel cas, tu ne peux pas utiliser l'histogramme (restons en 2D, sans faire intervenir le temps) pour comparer tout ou partie des 2 images.

    Avec un histogramme tu "t'assois" sur les positions des pixels

  9. #9
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut
    Question: Est-ce que seuls certains pixels doivent être identiques et que les autres seront différents ou bien les deux images doivent être identiques ?
    Non les deux images ne doivent pas être identiques.
    En fait, pour préciser c'est un peu comme un coloriage. A partir d'un fichier image modèle sans couleur, on veut vérifier que dans l'image coloriée, l'utilisateur n'a pas dépassé les limites du dessin par exemple..

  10. #10
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Je ne suis pas sur que l'exemple que tu donnes aide ... ou alors, si c'est vraiment ce que tu veux faire, ca va être beaucoup plus compliqué !

    déjà les limites de chaque zone de "coloriage" ... un "trait" sans épaisseur (avec des pixels) ?... ce n'est plus du tout la même histoire et ça met en oeuvre des techniques et des méthodes d'un tout autre ordre qu'une bête comparaison !

  11. #11
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut


    L'image PNG est toute petite.. de l'ordre de 100px sur 50px..
    Les limites de chaque zone de coloriage seraient sans épaisseur.. donc 1pixel normalement.

  12. #12
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    C'est donc bien une "comparaison" un peu spéciale...
    On dirait plutôt la vérification du bon fonctionnement d'un outil style "pot de peinture" (comme dans Paint, Photoshop ou encore Gimp).

    J'essaye de résumer.

    Ton modèle est une image vierge (blanche) avec seulement quelques pixels (noirs ?) qui délimitent des zones.
    Tu veux vérifier, dans la version "coloriée", que :

    • dans chaque zone, tous les pixels ont la même radiométrie (couleur)
    • chaque zone a sa propre radiométrie (?)
    • les pixels noirs du début sont toujours là (?)


    C'est ça ?

  13. #13
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut
    Oui c'est à peu près ça..
    "quelques pixels" : ça doit faire quand même au moins quelques centaines..

    Non, pas la même couleur dans la zone. Dans la ou les zones coloriées, l'utilisateur est libre de faire ce qu'il veut.. Colorier chaque pixel d'une couleur différente s'il veut.. tant qu'il reste dans les limites du dessin.
    Et les pixels du début seront toujours là... mais ne sont pas forcément noir.

    En complément (car je cherche aussi ), par rapport à ce que j'écrivais dans mon premier post, il n'y a pas de fonction permettant de retourner la valeur hexadécimale de la couleur d'un pixel donné dans une image ? (sous la forme coordonnées x,y = #CCCCCC par exemple)
    Il y serait alors relativement "simple" peut-être d'y mettre tous les codes hexa des pixels dans un dictionnaire (ou liste) et de comparer les 2 dictionnaire (celui de l'image modèle et celui de l'image finale).. Non ? Peut-être dans PIL... ?
    (c'est peut-être pas très clair cette idée.... je réfléchis tout haut )

  14. #14
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Tu n aurais pas un ou deux exemples sous la main ? Modèle et version coloriée pour fixer les idées

  15. #15
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut
    Je n'ai pas les modèles d'origine sous la main alors j'ai fait des dessins un peu différents mais je pense suffisant pour illustrer..

    L'image coloriée correcte : on voit bien que les contours des carrés et la forme sombre avec une pointe de jaune du dessin restent bien de la même couleur d'origine. Rien ne dépasse du dessin d'origine non plus...

    L'image coloriée incorrecte : du rouge sur les traits noirs et la forme sombre d'origine, un carré qui dépasse des bordures.. etc.... Bref, c'est pas bon du tout..
    Images attachées Images attachées    

  16. #16
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Pour valider tes images résultats, il faut en fait dresser une liste (général, pas forcément au sens Python) de pixels de l'image origine, coordonnées ET couleur, à retrouver dans l'image coloriée.

    Je ne sais pas si c'est toujours comme cela mais ton modèle (illustration_vide.png) est en mode RGBa (RGB classique plus une composante de transparence (ou d'opacité, c'est selon)) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Python 2.7.3 (default, Aug  1 2012, 05:16:07) 
    [GCC 4.6.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from PIL import Image
    >>> orig = Image.open('illustration_vide.png')
    >>> orig.mode
    'RGBA'
    >>>
    et tes pixels n'ont que deux valeurs distinctes de transparence/opacité

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> transparences = set(map(lambda (r,g,b,a):a,orig.getdata()))
    >>> transparences
    set([0, 255])
    Pour mettre en évidence les pixels qui ont une valeur de transparence à 0, je crée une nouvelle image en remplacant ces pixels par des pixels rouges :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> ROUGE = (255,0,0,255)
    >>> 
    >>> new = Image.new("RGBA",orig.size)
    >>> pixels = list(orig.getdata())
    >>> for p in range(len(pixels)):
    ...     if pixels[p][-1] == 0:
    ...             pixels[p] = ROUGE
    ... 
    >>> new.putdata(pixels)
    >>> new.save('transparences.png')
    Ca donne ça




    Et dans les pixels qui restent (dernière composante à 255), les pixels blancs sont vraiment blancs : rgba vaut (255,255,255,255). Coup de bol ou, par construction, c'est toujours comme ça ?

    Je le mets en évidence en les "coloriant" en vert :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> VERT = (0,255,0,255)
    >>> BLANC = (255,)*4
    >>> new = Image.new("RGBA",orig.size)
    >>> pixels = list(orig.getdata())
    >>> for p in range(len(pixels)):
    ...     if pixels[p] == BLANC:
    ...             pixels[p] = VERT
    ... 
    >>> new.putdata(pixels)
    >>> new.save('pixels_blancs.png')


    Il faut peut-être raffiner la méthode, notamment sur le bord de la tache "grisâtre" qui contient des pixels clairs mais pas complétement blancs (là, c'est toi qui peut le dire), mais j'ai l'impression qu'on récupère la zone "libre" du modèle où on a le droit le colorier.


    Donc, la "carte" des zones interdites ressemble à :
    1. la liste des positions où la transparence vaut 0
    2. les positions des pixels non totalement blancs et la couleur (un petit dictionnaire ?)


    Les positions des pixels transparents :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> transparences = list()
    >>> for colonne in range(orig.size[0]):
    ...     for ligne in range(orig.size[1]):
    ...             r,g,b,a = orig.getpixel((colonne,ligne))
    ...             if a == 0:
    ...                     transparences.append((colonne,ligne))
    ... 
    >>> transparences[0]
    (0, 0)
    >>> transparences[-1]
    (99, 49)

    vérifications sur les deux images résultats :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    >>> resultat_OK = Image.open('illustration_couleur_OK.png')
    >>> for position in transparences:
    ...     r,g,b,a = resultat_OK.getpixel(position)
    ...     if a != 0:
    ...             print "Ooops", position, a
    ... 
    >>> 
    >>> resultat_KO = Image.open('illustration_couleur_Erreur.png')
    >>> for position in transparences:
    ...     r,g,b,a = resultat_KO.getpixel(position)
    ...     if a != 0:
    ...             print "Ooops", position, a
    ... 
    Ooops (1, 9) 255
    Ooops (1, 10) 255
    Ooops (1, 11) 255
    Ooops (1, 12) 255
    Ooops (1, 13) 255
    Ooops (1, 14) 255
    Ooops (1, 15) 255
    Ooops (1, 16) 255
    Ooops (1, 17) 255
    Ooops (1, 18) 255
    Ooops (1, 19) 255
    Ooops (1, 20) 255
    Ooops (1, 21) 255
    Ooops (1, 22) 255
    Ooops (1, 23) 255
    Ooops (1, 24) 255
    Ooops (1, 25) 255
    Ooops (1, 26) 255
    Ooops (1, 27) 255
    Ooops (1, 28) 255
    Ooops (1, 29) 255
    Ooops (1, 30) 255
    Ooops (1, 31) 255
    Ooops (1, 32) 255
    Ooops (1, 33) 255
    Ooops (2, 9) 255
    Ooops (2, 10) 255
    Ooops (2, 11) 255
    Ooops (2, 12) 255
    Ooops (2, 13) 255
    Ooops (2, 14) 255
    Ooops (2, 15) 255
    Ooops (2, 16) 255
    Ooops (2, 17) 255
    Ooops (2, 18) 255
    Ooops (2, 19) 255
    Ooops (2, 20) 255
    Ooops (2, 21) 255
    Ooops (2, 22) 255
    Ooops (2, 23) 255
    Ooops (2, 24) 255
    Ooops (2, 25) 255
    Ooops (2, 26) 255
    Ooops (2, 27) 255
    Ooops (2, 28) 255
    Ooops (2, 29) 255
    Ooops (2, 30) 255
    Ooops (2, 31) 255
    Ooops (2, 32) 255
    Ooops (2, 33) 255
    Ooops (3, 9) 255
    Ooops (3, 10) 255
    Ooops (3, 11) 255
    Ooops (3, 12) 255
    Ooops (3, 13) 255
    Ooops (3, 14) 255
    Ooops (3, 15) 255
    Ooops (3, 16) 255
    Ooops (3, 17) 255
    Ooops (3, 18) 255
    Ooops (3, 19) 255
    Ooops (3, 20) 255
    Ooops (3, 21) 255
    Ooops (3, 22) 255
    Ooops (3, 23) 255
    Ooops (3, 24) 255
    Ooops (3, 25) 255
    Ooops (3, 26) 255
    Ooops (3, 27) 255
    Ooops (3, 28) 255
    Ooops (3, 29) 255
    Ooops (3, 30) 255
    Ooops (3, 31) 255
    Ooops (3, 32) 255
    Ooops (3, 33) 255
    Ooops (4, 9) 255
    Ooops (4, 10) 255
    Ooops (4, 11) 255
    Ooops (4, 12) 255
    Ooops (4, 13) 255
    Ooops (4, 14) 255
    Ooops (4, 15) 255
    Ooops (4, 16) 255
    Ooops (4, 17) 255
    Ooops (4, 18) 255
    Ooops (4, 19) 255
    Ooops (4, 20) 255
    Ooops (4, 21) 255
    Ooops (4, 22) 255
    Ooops (4, 23) 255
    Ooops (4, 24) 255
    Ooops (4, 25) 255
    Ooops (4, 26) 255
    Ooops (4, 27) 255
    Ooops (4, 28) 255
    Ooops (4, 29) 255
    Ooops (4, 30) 255
    Ooops (4, 31) 255
    Ooops (4, 32) 255
    Ooops (4, 33) 255
    Ooops (5, 9) 255
    Ooops (5, 10) 255
    Ooops (5, 11) 255
    Ooops (5, 12) 255
    Ooops (5, 13) 255
    Ooops (5, 14) 255
    Ooops (5, 15) 255
    Ooops (5, 16) 255
    Ooops (5, 17) 255
    Ooops (5, 18) 255
    Ooops (5, 19) 255
    Ooops (5, 20) 255
    Ooops (5, 21) 255
    Ooops (5, 22) 255
    Ooops (5, 23) 255
    Ooops (5, 24) 255
    Ooops (5, 25) 255
    Ooops (5, 26) 255
    Ooops (5, 27) 255
    Ooops (5, 28) 255
    Ooops (5, 29) 255
    Ooops (5, 30) 255
    Ooops (5, 31) 255
    Ooops (5, 32) 255
    Ooops (5, 33) 255
    Ooops (6, 9) 255
    Ooops (6, 10) 255
    Ooops (6, 11) 255
    Ooops (6, 12) 255
    Ooops (6, 13) 255
    Ooops (6, 14) 255
    Ooops (6, 15) 255
    Ooops (6, 16) 255
    Ooops (6, 17) 255
    Ooops (6, 18) 255
    Ooops (6, 19) 255
    Ooops (6, 20) 255
    Ooops (6, 21) 255
    Ooops (6, 22) 255
    Ooops (6, 23) 255
    Ooops (6, 24) 255
    Ooops (6, 25) 255
    Ooops (6, 26) 255
    Ooops (6, 27) 255
    Ooops (6, 28) 255
    Ooops (6, 29) 255
    Ooops (6, 30) 255
    Ooops (6, 31) 255
    Ooops (6, 32) 255
    Ooops (6, 33) 255
    Ooops (7, 9) 255
    Ooops (7, 10) 255
    Ooops (7, 11) 255
    Ooops (7, 12) 255
    Ooops (7, 13) 255
    Ooops (7, 14) 255
    Ooops (7, 15) 255
    Ooops (7, 16) 255
    Ooops (7, 17) 255
    Ooops (7, 18) 255
    Ooops (7, 19) 255
    Ooops (7, 20) 255
    Ooops (7, 21) 255
    Ooops (7, 22) 255
    Ooops (7, 23) 255
    Ooops (7, 24) 255
    Ooops (7, 25) 255
    Ooops (7, 26) 255
    Ooops (7, 27) 255
    Ooops (7, 28) 255
    Ooops (7, 29) 255
    Ooops (7, 30) 255
    Ooops (7, 31) 255
    Ooops (7, 32) 255
    Ooops (7, 33) 255
    Ooops (8, 9) 255
    Ooops (8, 10) 255
    Ooops (8, 11) 255
    Ooops (8, 12) 255
    Ooops (8, 13) 255
    Ooops (8, 14) 255
    Ooops (8, 15) 255
    Ooops (8, 16) 255
    Ooops (8, 17) 255
    Ooops (8, 18) 255
    Ooops (8, 19) 255
    Ooops (8, 20) 255
    Ooops (9, 9) 255
    Ooops (9, 10) 255
    Ooops (9, 11) 255
    Ooops (9, 12) 255
    Ooops (9, 13) 255
    Ooops (9, 14) 255
    Ooops (9, 15) 255
    Ooops (9, 16) 255
    Ooops (9, 17) 255
    Ooops (9, 18) 255
    Ooops (9, 19) 255
    Ooops (9, 20) 255
    Ooops (10, 9) 255
    Ooops (10, 10) 255
    Ooops (10, 11) 255
    Ooops (10, 12) 255
    Ooops (10, 13) 255
    Ooops (10, 14) 255
    Ooops (10, 15) 255
    Ooops (10, 16) 255
    Ooops (10, 17) 255
    Ooops (10, 18) 255
    Ooops (10, 19) 255
    Ooops (10, 20) 255
    Ooops (11, 9) 255
    Ooops (11, 10) 255
    Ooops (11, 11) 255
    Ooops (11, 12) 255
    Ooops (11, 13) 255
    Ooops (11, 14) 255
    Ooops (11, 15) 255
    Ooops (11, 16) 255
    Ooops (11, 17) 255
    Ooops (11, 18) 255
    Ooops (11, 19) 255
    Ooops (11, 20) 255
    Ooops (12, 9) 255
    Ooops (12, 10) 255
    Ooops (12, 11) 255
    Ooops (12, 12) 255
    Ooops (12, 13) 255
    Ooops (12, 14) 255
    Ooops (12, 15) 255
    Ooops (12, 16) 255
    Ooops (12, 17) 255
    Ooops (12, 18) 255
    Ooops (12, 19) 255
    Ooops (12, 20) 255
    Ooops (13, 9) 255
    Ooops (13, 10) 255
    Ooops (13, 11) 255
    Ooops (13, 12) 255
    Ooops (13, 13) 255
    Ooops (13, 14) 255
    Ooops (13, 15) 255
    Ooops (13, 16) 255
    Ooops (13, 17) 255
    Ooops (13, 18) 255
    Ooops (13, 19) 255
    Ooops (13, 20) 255
    Ooops (14, 9) 255
    Ooops (14, 10) 255
    Ooops (14, 11) 255
    Ooops (14, 12) 255
    Ooops (14, 13) 255
    Ooops (14, 14) 255
    Ooops (14, 15) 255
    Ooops (14, 16) 255
    Ooops (14, 17) 255
    Ooops (14, 18) 255
    Ooops (14, 19) 255
    Ooops (14, 20) 255
    Ooops (15, 9) 255
    Ooops (15, 10) 255
    Ooops (15, 11) 255
    Ooops (15, 12) 255
    Ooops (15, 13) 255
    Ooops (15, 14) 255
    Ooops (15, 15) 255
    Ooops (15, 16) 255
    Ooops (15, 17) 255
    Ooops (15, 18) 255
    Ooops (15, 19) 255
    Ooops (15, 20) 255
    Ooops (16, 9) 255
    Ooops (16, 10) 255
    Ooops (16, 11) 255
    Ooops (16, 12) 255
    Ooops (16, 13) 255
    Ooops (16, 14) 255
    Ooops (16, 15) 255
    Ooops (16, 16) 255
    Ooops (16, 17) 255
    Ooops (16, 18) 255
    Ooops (16, 19) 255
    Ooops (16, 20) 255
    Ooops (17, 9) 255
    Ooops (17, 10) 255
    Ooops (17, 11) 255
    Ooops (17, 12) 255
    Ooops (17, 13) 255
    Ooops (17, 14) 255
    Ooops (17, 15) 255
    Ooops (17, 16) 255
    Ooops (17, 17) 255
    Ooops (17, 18) 255
    Ooops (17, 19) 255
    Ooops (17, 20) 255
    Ooops (18, 9) 255
    Ooops (18, 10) 255
    Ooops (18, 11) 255
    Ooops (18, 12) 255
    Ooops (18, 13) 255
    Ooops (18, 14) 255
    Ooops (18, 15) 255
    Ooops (18, 16) 255
    Ooops (18, 17) 255
    Ooops (18, 18) 255
    Ooops (18, 19) 255
    Ooops (18, 20) 255
    Ooops (60, 7) 255
    Ooops (60, 8) 255
    Ooops (60, 9) 255
    Ooops (61, 7) 255
    Ooops (61, 8) 255
    Ooops (61, 9) 255
    >>>
    Et pour les couleurs imposées :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> obligatoires = dict()
    >>> for colonne in range(orig.size[0]):
    ...     for ligne in range(orig.size[1]):
    ...             r,g,b,a = orig.getpixel((colonne,ligne))
    ...             if a == 255 and (r,g,b) != (255,255,255):
    ...                     obligatoires[(colonne,ligne)] = (r,g,b,a)
    ... 
    >>> len(obligatoires)
    607
    Et sur les images résultats :


    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    >>> resultat_OK = Image.open('illustration_couleur_OK.png')
    >>> for position,rgba in obligatoires.iteritems():
    ...     couleur = resultat_OK.getpixel(position)
    ...     if couleur != rgba:
    ...             print "Ooops", position, couleur, "attendu", rgba
    ... 
    Ooops (36, 17) (38, 188, 255, 255) attendu (249, 249, 249, 255)
    Ooops (46, 17) (255, 61, 222, 255) attendu (243, 243, 243, 255)
    >>> 
    >>> 
    >>> resultat_KO = Image.open('illustration_couleur_Erreur.png')
    >>> for position,rgba in obligatoires.iteritems():
    ...     couleur = resultat_KO.getpixel(position)
    ...     if couleur != rgba:
    ...             print "Ooops", position, couleur, "attendu", rgba
    ... 
    Ooops (51, 34) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (51, 31) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 25) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (38, 9) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (8, 33) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (51, 36) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (59, 11) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (43, 9) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (8, 27) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (61, 10) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (42, 15) (255, 0, 0, 255) attendu (255, 216, 0, 255)
    Ooops (43, 14) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (44, 9) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (45, 12) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (11, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (39, 14) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (51, 33) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (37, 9) (255, 0, 0, 255) attendu (255, 216, 0, 255)
    Ooops (51, 38) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 22) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 29) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (41, 14) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (17, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (38, 13) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (39, 8) (255, 0, 0, 255) attendu (255, 216, 0, 255)
    Ooops (13, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (51, 35) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (51, 40) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 24) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (9, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (44, 14) (255, 0, 0, 255) attendu (255, 216, 0, 255)
    Ooops (8, 31) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (14, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 32) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (51, 37) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (51, 30) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 26) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (60, 10) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (15, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (16, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (43, 15) (255, 0, 0, 255) attendu (255, 216, 0, 255)
    Ooops (44, 8) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (45, 13) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (38, 14) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (12, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (36, 17) (38, 188, 255, 255) attendu (249, 249, 249, 255)
    Ooops (51, 39) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 21) (255, 0, 0, 255) attendu (48, 48, 48, 255)
    Ooops (59, 10) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (43, 8) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (8, 28) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (40, 14) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (41, 15) (255, 0, 0, 255) attendu (255, 216, 0, 255)
    Ooops (18, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (39, 9) (255, 0, 0, 255) attendu (255, 216, 0, 255)
    Ooops (51, 32) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (46, 17) (255, 61, 222, 255) attendu (243, 243, 243, 255)
    Ooops (57, 10) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (8, 23) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (58, 10) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (59, 12) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (10, 21) (255, 0, 0, 255) attendu (0, 0, 0, 255)
    Ooops (44, 13) (255, 0, 0, 255) attendu (64, 64, 64, 255)
    Ooops (8, 30) (255, 0, 0, 255) attendu (0, 0, 0, 255)

    Il y a 2 erreurs sur le résultat à priori bon. C'est situé sur le pourtour de la "tache" à conserver. C'est juste, comme je l'écrivais plus haut, un petit raffinement à faire dans la distinction entre pixels à garder et pixels libres mais, à la louche, ça fonctionne il me semble.

    mais attention : ca se base sur le mode RGBA et sur les pixels vraiment blancs. Est-ce toujours le cas ? ... il faut peut-être adapter deux ou trois trucs

  17. #17
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Précision supplémentaire.

    Pourquoi je ne me suis pas uniquement basé sur les pixels blancs (r , g et b à 255) mais aussi sur la transparence ?

    C'est parce qu'il existe des pixels blancs avec une composante alpha à 0, et pas qu'un peu :

    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
    >>> from PIL import Image
    >>> orig = Image.open('illustration_vide.png')
    >>> pixels = filter(lambda (r,g,b,a):(r,g,b) == (255,)*3,orig.getdata())
    >>> pixels = set(pixels)
    >>> pixels
    set([(255, 255, 255, 0), (255, 255, 255, 255)])
    >>> 
    >>> pixels = filter(lambda (r,g,b,a):(r,g,b) == (255,)*3,orig.getdata())
    >>> 
    >>> compteur = dict()
    >>> for pixel in pixels:
    ...     compteur[pixel] = compteur.get(pixel,0) + 1
    ... 
    >>> compteur
    {(255, 255, 255, 0): 2172, (255, 255, 255, 255): 2213}
    >>>

  18. #18
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut
    Wouaw !
    Je regarderai en détail et testerai en sortant du boulot ce soir mais à première vue, ça me semble plutôt bien analysé (concernant l'interprétation en RGBa) et pour répondre à ta question, oui les pixels blancs sont vraiment blancs..

    J'espère ne pas t'avoir empéché de dormir en tout cas...

    A suivre...

  19. #19
    Membre confirmé Avatar de memento80
    Homme Profil pro
    Boulot : ne rentre pas dans une case
    Inscrit en
    Novembre 2004
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Boulot : ne rentre pas dans une case
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2004
    Messages : 163
    Par défaut
    J'ai pu me pencher un peu plus en détail sur ta proposition et c'est exactement ce que je cherchais à faire

    Merci aussi pour les explications limpides qui vont avec..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comparer deux images (100% identiques ou non)
    Par FluidBlow dans le forum C++Builder
    Réponses: 3
    Dernier message: 12/04/2008, 13h40
  2. Comparer deux images
    Par GwenZephyr dans le forum Windows Forms
    Réponses: 6
    Dernier message: 04/03/2008, 16h09
  3. comparer deux images en vbnet
    Par offspring dans le forum VB.NET
    Réponses: 9
    Dernier message: 06/11/2007, 14h13
  4. comparer deux images
    Par alex01pernot dans le forum Delphi
    Réponses: 4
    Dernier message: 03/04/2007, 16h08
  5. Comparer deux images pas directement superposables
    Par Byhias dans le forum Images
    Réponses: 2
    Dernier message: 12/03/2007, 16h41

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