Quel est le moyen le plus rapide de dessiner une image à partir de valeurs de pixels discrets en Python?

StackOverflow https://stackoverflow.com/questions/434583

Question

Je souhaite dessiner une image basée sur les valeurs de pixel calculées, afin de visualiser certaines données. Essentiellement, je souhaite prendre une matrice bidimensionnelle de triplets de couleurs et la rendre.

Notez que ce n’est pas un traitement d’image, car je ne transforme pas une image existante, ni aucune sorte de transformations d’image entière, et ce n’est pas non plus un graphique vectoriel car il n’existe pas de structure prédéterminée pour l’image. ' m rendu - je vais probablement produire des blobs amorphes de couleur, pixel par pixel.

Je dois restituer des images d’environ 1kx1k pixels pour l’instant, mais il serait utile d’avoir un système évolutif. Le format cible final est PNG ou tout autre format sans perte.

J'utilise PIL en ce moment via le draw.point d'ImageDraw et je me demandais, étant donné les fonctionnalités très spécifiques et relativement basiques dont j'ai besoin, y a-t-il une bibliothèque plus rapide disponible?

Était-ce utile?

La solution

Si vous avez numpy et scipy (et si vous manipulez de grands tableaux en Python, je les recommanderais), le scipy.misc.pilutil.toimage fonction est très pratique. Un exemple simple:

import numpy as np
import scipy.misc as smp

# Create a 1024x1024x3 array of 8 bit unsigned integers
data = np.zeros( (1024,1024,3), dtype=np.uint8 )

data[512,512] = [254,0,0]       # Makes the middle pixel red
data[512,513] = [0,0,255]       # Makes the next pixel blue

img = smp.toimage( data )       # Create a PIL image
img.show()                      # View in default viewer

La bonne chose est que toimage gère très bien différents types de données. Ainsi, un tableau 2D de nombres à virgule flottante est sensiblement converti en niveaux de gris, etc.

Vous pouvez télécharger numpy et scipy à partir de ici . Ou en utilisant pip:

pip install numpy scipy

Autres conseils

import Image
im= Image.new('RGB', (1024, 1024))
im.putdata([(255,0,0), (0,255,0), (0,0,255)])
im.save('test.png')

Place un pixel rouge, vert et bleu en haut à gauche de l'image.

im.fromstring () est encore plus rapide si vous préférez traiter les valeurs d'octet.

Configuration requise

Pour cet exemple, installez Numpy et Oreiller .

Exemple

Le but est d'abord de représenter l'image que vous voulez créer sous forme de tableaux d'ensembles de 3 nombres (RVB) - utilisez le array () , pour la performance et la simplicité:

import numpy

data = numpy.zeros((1024, 1024, 3), dtype=numpy.uint8)

Maintenant, définissez les valeurs RVB des 3 pixels du milieu en rouge, vert et bleu:

data[512, 511] = [255, 0, 0]
data[512, 512] = [0, 255, 0]
data[512, 513] = [0, 0, 255]

Ensuite, utilisez le de Pillow. Image.fromarray () pour générer une image à partir du tableau:

from PIL import Image

image = Image.fromarray(data)

Maintenant, " montrer " l'image (sous OS X, cela l'ouvrira en tant que fichier temporaire dans Aperçu):

image.show()

Remarque

Cette réponse est inspirée de la réponse de BADCODE, trop obsolète pour être utilisée et trop différente pour être simplement mise à jour sans réécriture complète.

Une autre approche consiste à utiliser Pyxel , une implémentation open source de l'API TIC-80 en Python3 (TIC-80 est le code source ouvert PICO-8).

Voici une application complète qui dessine un pixel jaune sur un fond noir:

import pyxel

def update():

    """This function just maps the Q key to `pyxel.quit`,
    which works just like `sys.exit`."""

    if pyxel.btnp(pyxel.KEY_Q): pyxel.quit()

def draw():

    """This function clears the screen and draws a single
    pixel, whenever the buffer needs updating. Note that
    colors are specified as palette indexes (0-15)."""

    pyxel.cls(0)            # clear screen (color)
    pyxel.pix(10, 10, 10)   # blit a pixel (x, y, color)

pyxel.init(160, 120)        # initilize gui (width, height)
pyxel.run(update, draw)     # run the game  (*callbacks)

Remarque : la bibliothèque n'autorise que seize couleurs, mais vous pouvez modifier les couleurs. Vous pouvez probablement la faire en supporter davantage sans trop de travail.

Je pense que vous utilisez PIL pour générer un fichier image sur le disque, puis vous le chargez avec un logiciel de lecture d'images.

Vous devriez obtenir une légère amélioration de vitesse en rendant directement l’image en mémoire (vous économiserez le coût d’écriture de l’image sur le disque, puis de le recharger). Consultez ce fil https://stackoverflow.com/questions/326300/python-best- bibliothèque de dessin pour savoir comment restituer cette image avec divers modules Python.

J'essayerais personnellement wxpython et la fonction dc.DrawBitmap . Si vous utilisez un tel module plutôt qu'un lecteur d'image externe, vous aurez de nombreux avantages:

  • vitesse
  • vous pourrez créer une interface utilisateur interactive avec des boutons pour les paramètres.
  • vous pourrez programmer facilement une fonction Zoomin et Zoomout
  • vous pourrez tracer l'image au fur et à mesure que vous la calculez, ce qui peut être très utile si le calcul prend beaucoup de temps
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top