“TypeError: 'int' object is not iterable” on gresycale image

“TypeError: 'int' object is not iterable” on gresycale image

我有一个图像处理程序,它的一个功能是与用户选择的图像形成对比。但是在灰度图像的情况下,我得到以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\EduPython\App\lib\tkinter\__init__.py", line 1456, in __call__
    return self.func(*args)
  File "C:\Users\megzari.nassim\Desktop\Projet Complet\Test 2.py", line 194, in use_contrast
    result = change_contrast(S2.get())
  File "C:\Users\megzari.nassim\Desktop\Projet Complet\Test 2.py", line 188, in change_contrast
    new_color = tuple(int(factor * (c-128) + 128) for c in color)
TypeError: 'int' object is not iterable

我尝试将 color 变量重新转换为 RGB,但仍然无效。

这里是这个错误的代码位:

def change_contrast(level):

    img = Image.open(a)
    img.load()

    factor = (259 * (level+255)) / (255 * (259-level))
    for x in range(img.size[0]):
        for y in range(img.size[1]):
            color = img.getpixel((x, y))
            new_color = tuple(int(factor * (c-128) + 128) for c in color)
            img.putpixel((x, y), new_color)

    return img

如果您需要完整代码,请看这里:

from tkinter import*
import tkinter as Tkinter
from tkinter import filedialog, DISABLED, messagebox as tkMessageBox
import os
import ntpath
from PIL import Image, ImageTk, ImageFilter
import PIL
from collections import Counter
from random import randint
import random
import PIL.ImageOps


def EchelleDeGris():
    Ima2=Image.new("RGB",(z[0],z[1]))
    px=Ima1.load()
    px1=Ima2.load()
    for x in range(z[0]):
        for y in range(z[1]):
            p=px[x,y]
            if type(p)==int:
                p=(p,p,p)
            o=int((p[0]+p[1]+p[2])/3)
            px1[x,y]=(o,o,o)
    Ima2.save(""+dir_path+"\Requirements\ImageMod.png")
    im2 = ImageTk.PhotoImage(file=""+dir_path+"\Requirements\ImageMod.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=4, columnspan =4)

def SupprimerImage():
    I2 = Tkinter.Label(main, image=imt)
    I2.grid(row=0, column=4, columnspan =4)

def Luminosite():
    Ima2=Image.new("RGB",(z[0],z[1]))
    px=Ima1.load()
    px1=Ima2.load()
    for x in range(z[0]):
        for y in range(z[1]):
            p=px[x,y]
            if type(p)==int:
                p=(p,p,p)
            px1[x,y]=(p[0]+S1.get(),p[1]+S1.get(),p[2]+S1.get())
    Ima2.save(""+dir_path+"\Requirements\ImageMod.png")
    im2 = ImageTk.PhotoImage(file=""+dir_path+"\Requirements\ImageMod.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=4, columnspan =4)

def AnnulerModifications():
    I2 = Tkinter.Label(main, image=im1)
    I2.grid(row=0, column=4, columnspan =4)

def get_pixel(pixels, x, y):
    try:
        return pixels[x, y]
    except IndexError:
        return None


def get_neighbors(pixels, x, y):
    neighbors = list()
    neighbors.append(get_pixel(pixels, x, y - 1))
    neighbors.append(get_pixel(pixels, x, y + 1))
    neighbors.append(get_pixel(pixels, x - 1, y))
    neighbors.append(get_pixel(pixels, x + 1, y))
    neighbors.append(get_pixel(pixels, x - 1, y - 1))
    neighbors.append(get_pixel(pixels, x - 1, y + 1))
    neighbors.append(get_pixel(pixels, x + 1, y - 1))
    neighbors.append(get_pixel(pixels, x + 1, y + 1))
    return neighbors


def filter_art(pixels, size):
    indexes = dict()
    for x in range(size[0]):
        for y in range(size[1]):
            color = get_pixel(pixels, x, y)
            neighbors = get_neighbors(pixels, x, y)
            new_color = Counter(neighbors).most_common()[0][0]
            if new_color is not None:
                indexes[x, y] = new_color
    for x, y in indexes:
        pixels[x, y] = indexes[x, y]


def pop_art(path_orig, path_mod, coef):

    s=[]
    for i in range(9):

        r=(randint(0,255), randint(0,255), randint(0,255))
        g=(randint(0,255), randint(0,255), randint(0,255))
        b=(randint(0,255), randint(0,255), randint(0,255))

        image_orig = Image.open(path_orig)
        size = image_orig.size
        image_mod = Image.new("RGB",(size[0],size[1]))
        pixels_orig = image_orig.load()
        pixels_mod = image_mod.load()
        for x in range(size[0]):
            for y in range(size[1]):
                p = pixels_orig[x, y]
                if isinstance(p, int):
                    rgb = (p,p,p)
                elif isinstance(p, tuple) and len(p) in (3, 4):
                    rgb = p[:3]
                else:
                    raise TypeError('Unknown pallete')
                average_color = sum(rgb) / 3
                if average_color <= 85:
                    pixels_mod[x, y] = r
                elif 85 < average_color <= 170:
                    pixels_mod[x, y] = g
                elif average_color > 170:
                    pixels_mod[x, y] = b
        for _ in range(coef):
            filter_art(pixels_mod, size)
        image_mod.save(''+dir_path+'\PopArt\Modified Images\result'+str(i)+'.png')
        Img=[None]*9
    for i in range(9):
        Img[i]=Image.open(""+dir_path+"\PopArt\Modified Images\result"+str(i)+".png")
        basewidth = int(Img[i].size[1]/3)
        wpercent = (basewidth / float(Img[i].size[0]))
        hsize = int((float(Img[i].size[1]) * float(wpercent )))
        Img[i] = Img[i].resize((basewidth , hsize ), PIL.Image.ANTIALIAS)
        Img[i].save(''+dir_path+'\PopArt\Resized Images\resized_image'+str(i)+'.png')


    Img1=[None]*9
    pixels1=[None]*9
    Imaz=Image.new("RGB",(basewidth*3,hsize*3))
    pixels=Imaz.load()
    for i in range(9):
        Img1[i]=Image.open(''+dir_path+'\PopArt\Resized Images\resized_image'+str(i)+'.png')
        pixels1[i]=Img1[i].load()


    for x in range(0,basewidth):
        for y in range(0,hsize):
            pixels[x,y]=pixels1[0][x,y]
        for y in range(hsize,hsize*2):
            pixels[x,y]=pixels1[1][x,y-hsize]
        for y in range(hsize*2,hsize*3):
            pixels[x,y]=pixels1[2][x,y-hsize*2]

    for x in range(basewidth,basewidth*2):
        for y in range(0,hsize):
            pixels[x,y]=pixels1[3][x-basewidth,y]
        for y in range(hsize,hsize*2):
            pixels[x,y]=pixels1[4][x-basewidth,y-hsize]
        for y in range(hsize*2,hsize*3):
            pixels[x,y]=pixels1[5][x-basewidth,y-hsize*2]

    for x in range(basewidth*2,basewidth*3):
        for y in range(0,hsize):
            pixels[x,y]=pixels1[6][x-basewidth*2,y]
        for y in range(hsize,hsize*2):
            pixels[x,y]=pixels1[7][x-basewidth*2,y-hsize]
        for y in range(hsize*2,hsize*3):
            pixels[x,y]=pixels1[8][x-basewidth*2,y-hsize*2]
    Imaz = Imaz.resize((size[0] , size[1] ), PIL.Image.ANTIALIAS)
    Imaz.save(""+dir_path+"\PopArt\Result Image\result.png")


def usepop():
    im2 = ImageTk.PhotoImage(file=""+dir_path+"\Requirements\traitement.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=4, columnspan =4)
    I2.update_idletasks()
    pop_art(a, None, coef=4)
    im2 = ImageTk.PhotoImage(file=""+dir_path+"\PopArt\Result Image\result.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=4, columnspan =4)

def change_contrast(level):

    img = Image.open(a)
    img.load()

    factor = (259 * (level+255)) / (255 * (259-level))
    for x in range(img.size[0]):
        for y in range(img.size[1]):
            color = img.getpixel((x, y))
            new_color = tuple(int(factor * (c-128) + 128) for c in color)
            img.putpixel((x, y), new_color)

    return img

def use_contrast():
    result = change_contrast(S2.get())
    result.save(""+dir_path+"\Requirements\ImageMod.png")
    im2 = ImageTk.PhotoImage(file=""+dir_path+"\Requirements\ImageMod.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=4, columnspan =4)

def recherche_contours():
    Ima2=Image.new("RGB",(z[0],z[1]))
    px=Ima1.load()
    px1=Ima2.load()
    for x in range(z[0]):
        for y in range(z[1]):
            p=px[x,y]
            if type(p)==int:
                p=(p,p,p)
            o=int((p[0]+p[1]+p[2])/3)
            px1[x,y]=(o,o,o)
    Ima2 = Ima2.filter(ImageFilter.FIND_EDGES)
    image = Ima2
    if image.mode == 'RGBA':
        r,g,b,a = image.split()
        rgb_image = Image.merge('RGB', (r,g,b))

        inverted_image = PIL.ImageOps.invert(rgb_image)

        r2,g2,b2 = inverted_image.split()

        final_transparent_image = Image.merge('RGBA', (r2,g2,b2,a))

        final_transparent_image.save(""+dir_path+"\Requirements\ImageMod.png")

    else:
        inverted_image = PIL.ImageOps.invert(image)
        inverted_image.save(""+dir_path+"\Requirements\ImageMod.png")
    im2 = ImageTk.PhotoImage(file=""+dir_path+"\Requirements\ImageMod.png")
    main.image = im2
    I2 = Tkinter.Label(main, image=im2)
    I2.grid(row=0, column=4, columnspan =4)

main=Tk()

main.withdraw()
a = filedialog.askopenfilename()
main.deiconify()

dir_path = os.path.dirname(os.path.realpath("Test2.py"))

main.configure(background="#a1dbcd")
main.title("Photoshop Version.Megzari")

Ima1=Image.open(a)
z=Ima1.size
nux=Image.new("RGB",(z[0],z[1]))
nuxy=nux.load()
for x in range(z[0]):
    for y in range(z[1]):
        nuxy[x,y]=(255,255,255)
nux.save(""+dir_path+"\Requirements\Blank.png")


if z>(400,400):
    main.withdraw()
    tkMessageBox.showinfo( "Resolution Error", "The image is too big, please select a smaller one.")
    sys.exit()


elif z<(400,400):
    im1 = ImageTk.PhotoImage(file=a)
    I1 = Tkinter.Label(main, image=im1)
    I1.grid(row=0, column=1, columnspan =3)
    imt = ImageTk.PhotoImage(file=""+dir_path+"\Requirements\Blank.png")
    T1 = Tkinter.Label(main, image=imt)
    T1.grid(row=0, column=4, columnspan =4)
    B1 = Tkinter.Button(main, text ="Echelle de gris", command = EchelleDeGris, fg="#a1dbcd", bg="#383a39", state=NORMAL)
    B1.grid(padx=20, pady=20, row=1, column=0)
    B3 = Tkinter.Button(main, text ="Appliquer Luminosité", command = Luminosite, fg="#a1dbcd", bg="#383a39")
    B3.grid(padx=20, pady=20, row=1, column=1)
    S1 = Scale(main, from_=0, to=254, orient=HORIZONTAL, fg="#a1dbcd", bg="#383a39", length = 200)
    S1.grid(row=2, column=1)
    B2 = Tkinter.Button(main, text ="Supprimer Image", command = SupprimerImage, fg="#a1dbcd", bg="#383a39")
    B2.grid(padx=20, pady=20, row=1, column=7)
    B3 = Tkinter.Button(main, text ="Annuler Modifications", command = AnnulerModifications, fg="#a1dbcd", bg="#383a39")
    B3.grid(padx=20, pady=20, row=1, column=6)
    B4 = Tkinter.Button(main, text ="Pop Art", command = usepop, fg="#a1dbcd", bg="#383a39")
    B4.grid(padx=20, pady=20, row=1, column=3)
    S2 = Scale(main, from_=-258, to=258, orient=HORIZONTAL, fg="#a1dbcd", bg="#383a39", length = 200)
    S2.grid(row=2, column=4)
    B4 = Tkinter.Button(main, text ="Appliquer Contraste", command = use_contrast, fg="#a1dbcd", bg="#383a39")
    B4.grid(padx=20, pady=20, row=1, column=4)
    B5 = Tkinter.Button(main, text ="Trouver Contours", command = recherche_contours, fg="#a1dbcd", bg="#383a39")
    B5.grid(padx=20, pady=20, row=1, column=5)

    s=S1.get()
    s2=S2.get()





main.mainloop()

编辑:我尝试使用:

if type(color)==int:
    color=(color,color,color)

它要求我在 new_color

上输入一个整数

来自documentation

.getpixel(xy)

Returns the pixel value or values at the given coordinates. For single-band images, returns a single number; a sequence of pixel values is returned for multi-band images. For example, if the top left pixel of an image im of mode "L" has value 128, then im.getpixel((0,0)) returns 128.

因此,它可以 return 单个值或元组。如果它是单个值,您将收到 not iterable 错误。这意味着你必须检查你从电话中得到了什么。

由于没有人可以回答这个简单的问题,所以我经过一系列测试和演习后发现了自己。 事实上,我所要做的就是检查 colortype()。如果它是 int,我将 color 设为一个元组。您可以通过分配:color=(color,color,color) 或以这种方式使其成为列表:color=[color,color,color]color=[color]*3 然后使其成为元组:color=tuple(color)。由于 new_color 现在将是一个元组,它仍然是 3 个相同的值,但是 img.putpixel((x, y), new_color) 需要一个整数,因此您只需通过编写 new_color=new_color[0] 来提取 new_color 的第一个值。如果 colortype() 不是 int,则您只需 运行 另一段代码而无需任何修改。这是上面那个的工作代码:

def change_contrast(level):

    img = Image.open(a)
    img.load()

    factor = (259 * (level+255)) / (255 * (259-level))
    for x in range(img.size[0]):
        for y in range(img.size[1]):
            color = img.getpixel((x, y))
            if type(color) == int:
                color=(color,color,color)
                new_color = tuple(int(factor * (c-128) + 128) for c in color)
                new_color = new_color[0]
                img.putpixel((x, y), new_color)
            elif type(color) != int:
                new_color = tuple(int(factor * (c-128) + 128) for c in color)
                img.putpixel((x, y), new_color)
    return img