À l'aide de l'Image.point() méthode dans le PIL pour manipuler les données de pixel

Je suis en utilisant le Python Imaging Library pour coloriser une image noir et blanc avec une table qui définit la couleur des liens. La table de recherche est tout simplement un 256-élément de la liste de RVB tuples:

>>> len(colors)
256
>>> colors[0]
(255, 237, 237)
>>> colors[127]
(50, 196, 33)
>>> 

Ma première version utilisé le getpixel() et putpixel() méthodes:

    for x in range(w):
        for y in range(h):
            pix = img.getpixel((x,y))
            img.putpixel((x,y), colors[pix[0]])

C'était horriblement lent. Un profile rapport a souligné la putpixel et getpixel méthodes comme les coupables. Une petite enquête (j'.e, lire les docs) et je trouve que "Noter que cette méthode est relativement lente." re: putpixel. (réelle de l'exécution: 53s dans putpixel et 50 getpixel pour une image de 1024x1024)

Basé sur la suggestion dans les docs, j'ai utilisé im.load() et l'accès direct aux pixels à la place:

    pixels = img.load()
    for x in range(w):
        for y in range(h):
            pix = pixels[x, y]
            pixels[x, y] = colors[pix[0]]                

Traitement accéléré par un ordre de grandeur, mais il est encore lent: environ 3,5 s pour traiter une image de 1024x1024.

Une étude plus approfondie de la PIL docs semble indiquer Image.point() est exactement prévu à cet effet:

im.point(table) => image

im.point(function) => image

Renvoie une copie de l'image où chaque pixel a été cartographiée par le biais de la table donnée. La table contient 256 valeurs par bande dans l'image. Si une fonction est utilisée au lieu de cela, il devrait prendre qu'un seul argument. La fonction est appelée une fois pour chaque valeur de pixel, et la table résultante est appliquée à toutes les bandes de l'image.

J'ai passé un peu de temps piratage autour de l'interface, mais n'arrive pas à sembler obtenir ce droit. Pardonnez mon ignorance, mais PIL de docs sont curt et je n'ai pas beaucoup de traitement de l'image de l'expérience. J'ai googlé un peu et tourna quelques exemples, mais rien que le fait de l'utilisation de "cliquer" pour moi. Ainsi, finalement, mes questions:

  • Est Image.point() le bon outil pour ce travail?
  • Quel format/structure ne Image.point() s'attendre à la table?
  • Quelqu'un peut ébaucher un exemple de mise en œuvre? Chaque itération que j'ai essayé jusqu'à présent, a terminé avec une noire droite de l'image.
InformationsquelleAutor J.J. | 2010-02-02