Comment puis-je écrire un filtre pour la bibliothèque d'imagerie python pour le format pgm plain ascii (P2). Le problème ici est que le filtre PIL de base suppose un nombre constant d'octets par pixel.Comment écrire un filtre d'image PIL pour le format pgm ordinaire?
Mon but est d'ouvrir feep.pgm avec Image.open(). Voir http://netpbm.sourceforge.net/doc/pgm.html ou ci-dessous.
Une autre solution est que je trouve un autre format de gris en ASCII bien documenté qui est supporté par PIL et tous les principaux programmes graphiques. Aucune suggestion?
feep.pgm:
P2
# feep.pgm
24 7
15
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 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 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 0 0 0
modifier: Merci pour la réponse, cela fonctionne ... mais je besoin d'une solution qui utilise Image.open(). La plupart des programmes python utilisent PIL pour manipuler les graphiques (google: python image open). Ainsi, je dois pouvoir enregistrer un filtre à PIL. Ensuite, je peux utiliser n'importe quel logiciel qui utilise PIL. Je pense maintenant principalement scipy, pylab, etc. programmes dépendants.
éditer Ok, je pense que je l'ai maintenant. Ci-dessous l'emballage pgm2pil.py:
import Image
import numpy
def pgm2pil(filename):
try:
inFile = open(filename)
header = None
size = None
maxGray = None
data = []
for line in inFile:
stripped = line.strip()
if stripped[0] == '#':
continue
elif header == None:
if stripped != 'P2': return None
header = stripped
elif size == None:
size = map(int, stripped.split())
elif maxGray == None:
maxGray = int(stripped)
else:
for item in stripped.split():
data.append(int(item.strip()))
data = numpy.reshape(data, (size[1],size[0]))/float(maxGray)*255
return numpy.flipud(data)
except:
pass
return None
def imageOpenWrapper(fname):
pgm = pgm2pil(fname)
if pgm is not None:
return Image.fromarray(pgm)
return origImageOpen(fname)
origImageOpen = Image.open
Image.open = imageOpenWrapper
Il y a une légère amélioration à la réponse de Misha. Image.open doit être sauvegardé afin d'éviter les boucles sans fin. Si retourne pgm2pil appels wrapper Aucun pgm2pil qui retourne Aucun qui appelle pgm2pil ...
est inférieure à la fonction de test (feep_false.pgm est un pgm malformé, par exemple « P2 » -> « toto » et lena.pgm est juste la fichier image):
import pgm2pil
import pylab
try:
pylab.imread('feep_false.pgm')
except IOError:
pass
else:
raise ValueError("feep_false should fail")
pylab.subplot(2,1,1)
a = pylab.imread('feep.pgm')
pylab.imshow(a)
pylab.subplot(2,1,2)
b = pylab.imread('lena.png')
pylab.imshow(b)
pylab.show()
Merci pour votre aide. Mais, pourquoi renvoyez-vous numpy.flipud (data)? Je dois retourner juste des données. – user1245262
C'était il y a longtemps quand je l'ai fait ... La raison en est que les images ne sont pas dans le système de coordonnées cartésiennes (axe Y inversé). IMHO images devraient être dans le système cartésien sans le flip (ou avec flip, je ne me souviens pas de quel côté). À la fin, ce qui précède montre correctement l'image lors de l'utilisation d'imread et d'imshow. – Juha
Ah ... c'est logique. J'aurais dû y penser. Merci encore. – user1245262