2010-09-28 5 views
1

J'essaie de faire un exercice dans la «Programmation Python de John Zelle: une introduction à l'informatique». J'ai téléchargé un paquet graphique spécial pour son livre (graphics.py, qui est sur le site Web lié). La question se lit comme suit:Python 3: Conversion d'image en niveaux de gris

Ecrivez un programme qui convertit une image couleur en niveaux de gris. L'utilisateur fournit le nom d'un fichier contenant une image GIF ou PPM et le programme charge l'image et affiche le fichier. Au clic de la souris, le programme convertit l'image en niveaux de gris. L'utilisateur est alors invité à entrer un nom de fichier pour stocker l'image en niveaux de gris.

Vous voudrez probablement revenir en arrière et examiner l'objet Image de la bibliothèque graphique (Section 4.8.4). L'idée de base pour convertir l'image est de la parcourir pixel par pixel et de convertir chacun d'une couleur à une nuance de gris appropriée. Un pixel gris créé en définissant ses composants rouge, vert et bleu pour avoir la même luminosité. Donc, color_rgb(0, 0, 0) est noir, color_rgb(255, 255, 255) est blanc, et color_rgb(127, 127, 127) est un gris "à mi-chemin" entre les deux. Vous devez utiliser une moyenne pondérée des valeurs rgb d'origine pour déterminer la luminosité du gris. Voici le pseudo-code pour l'algorithme de niveaux de gris [pour une raison quelconque le retrait de quatre l'espace ne fonctionne pas sur l'aperçu]:

for each row in the image: 
    for each column in the image: 
     r, g, b = get pixel information for current row and column 
     brightness = int(round(0.299r + 0.587g + 0.114b)) 
    update the image # to see progress row by row 

Note: les opérations de pixels dans la Image classe sont assez lents, donc vous voulez utiliser relativement petites images (pas 12 mégapixels) pour tester votre programme.


J'ai travaillé dessus pendant des heures. Ceci est la dernière version de mon code:

# grayscale.py 

from graphics import * 

def main(): 
    infileName = input("File name: ") 
    outfileName = input("Save to: ") 

    image = Image(Point(100,100), infileName) 
    width = image.getWidth() 
    height = image.getHeight() 
    win = GraphWin("rgb") 
    image.draw(win) 

    row = 0 
    column = 0 

    win.getMouse() 

    for row in range(200): 
     for column in range(200): 
      r, g, b = image.getPixel(row, column) 
      brightness = int(round(0.299 * r + 0.587 * g + 0.114 * b)) 
      image.setPixel(row, column, color_rgb(brightness, brightness, brightness)) 
      win.update() 

    win.getMouse() 
    win.close() 

main() 

Je suis finalement si Python ne me donne pas un message d'erreur. Mais tout le programme est de charger l'image, prendre quelques clics de souris, puis fermez. J'ai entré le fichier d'entrée sous le nom U: \ Mes images \ yay.gif et le fichier de sortie sous U: \ Mes images \ yay2.gif. Mais je viens de chercher sur mon ordinateur et U: \ My Pictures \ yay2.gif n'existe pas. Qu'est-ce que je fais mal? Au fait, ce n'est pas un cours - il n'y a pas d'instructeur à me demander.

Peut-être que je devrais suivre dans le poste à la place. J'ai ajouté la fonction de sauvegarde, mais j'ai obtenu une image avec une boîte en niveaux de gris 200x200 et le reste en couleur. Alors, voici quelques lignes: j'ai changé

win = GraphWin("rgb", width, height) 
for row in range(height): 
    for column in range(width): 

Et je reçois le message d'erreur suivant: retraçage (appel le plus récent en dernier):
fichier "C: \ Python31 \ grayscale.py", ligne 31, dans
main()
fichier "C: \ Python31 \ grayscale.py", à la ligne 22, dans le principal
r, g, b = image.getPixel (ligne, colonne)
fichier « C: \ Python31 \ lib \ graphics.py ", ligne 810, dans getPixel
value = self.img.get (x, y)
fichier "C: \ Python31 \ lib \ tkinter_ initialisation _.py", ligne 3301, dans get
self.tk.call de retour (self.name, 'get', x, y)
_tkinter.TclError : pyimage1 get: les coordonnées sont hors de portée

Je comprends que j'ai probablement besoin de changer le point d'ancrage de l'image au centre.Mais je ne peux le déterminer que par la largeur et la hauteur de l'image, et je dois d'abord avoir téléchargé l'image pour obtenir ces valeurs. Y at-il un travail autour?

Répondre

3

Vous ne sauvegardez pas l'image. Notez que la variable outfileName n'est jamais utilisée. Vous devriez le passer à une sorte de fonction de sauvegarde. a pris un coup d'œil à graphics.py, je pense que c'est ce que vous avez besoin:

EDIT

Pour résoudre le problème à elle seule la conversion d'un coin, faire à la place, l'ancien code n'a été convertissait la premier 200x200 pixels. J'ai aussi changé de range en xrange, pas nécessaire mais plus efficace.

for row in xrange(height): 
     for column in xrange(windth): 
+0

Merci. J'ai essayé cela - j'ai une nouvelle image enregistrée là où elle devrait être, mais la seule boîte de 200x200 dans le coin a été convertie en niveaux de gris. J'ai donc changé la quatrième ligne dans le deuxième bloc à win = GraphWin("rgb", width, height) et les plages dans les boucles pour la hauteur et la largeur, respectivement. J'ai cette erreur: – user460847

+0

Traceback (dernier appel dernier): Fichier "C: \ Python31 \ grayscale.py", ligne 31, dans principal() Fichier "C: \ Python31 \ grayscale.py", ligne 22, dans principal r, g, b = image.getPixel (ligne, colonne) Fichier "C: \ Python31 \ lib \ graphics.py", ligne 810, dans getPixel valeur = self.img.get (x, y) Fichier «C: \ Python31 \ lib \ tkinter \ __ init__.py», ligne 3301, dans get renvoient self.tk.call (self.name, 'get', x, y) _tkinter.TclError: pyimage1 get: coordonne hors de portée – user460847

+0

@ user460847, mis à jour pour résoudre le problème avec la boîte 200x200. – mikerobi

0

Je ne vois aucune utilisation de après qu'il est mis - en d'autres termes, vous semblez jamais, jamais sauver le résultat à ce fichier (ou tout autre fichier, pour cette question).

1

Je sais que c'est un vieux post mais. Je pense que votre problème est l'image réelle que vous utilisez. Changez la résolution de l'image à 200 pixels par pouce.

+1

Assurez-vous également que vous enregistrez l'image comme: newImg = image.save (outfileName) – Chucky

0

Meilleur pour rester simple. Le programme demande d'enregistrer le fichier, qui a été oublié à la fin, et d'utiliser getMouse() pour obtenir le "pixel courant" que vous utilisez getX() et getY(). Voici un meilleur exemple à l'aide graphics.py

grayscale.py

from graphics import* 

print("This program grayscales images\n")# intro 

def grayscale(): # Obtaining file 
    infile = input('In what file is the image?: ') 
    outfile = input('What file do you want it saved?: ') 

# Using image file to get dynamics of window. You don't have to create a window either to obtain it. 

    file = Image(Point(0,0), infile) 
    width = file.getWidth() 
    height = file.getHeight() 

# Getting center point of photo 
    cWidth = width/2 
    cHeight = height/2 
    cen = Point(cWidth, cHeight) 

# Ready for window 
    image = Image(cen,infile) 
    win = GraphWin("Grayscale Image", width, height) 
    image.draw(win) 


# Getting current Pixel for loop 
    p = win.getMouse() 
    x = p.getX() 
    y = p.getY() 

    for x in range(height): 
     for y in range(width): 
      r, g, b = image.getPixel(x, y) 
      gray = int(round(.299*r + .587*g + .114*b)) 
      image.setPixel(x,y, color_rgb(gray, gray, gray)) 
     # i accidentally mixed my x and y variable and it spit 
     # out a two-headed cyclops tee hee 
      win.update() 

# Click to exit 
    image.save(outfile) 
    win.getMouse() 
    win.close() 

grayscale() 
Questions connexes