0

I am required to calculate the percentage of green pixels in an image. To do that, I use the open() function to open and display the image and the calc_green() function to calculate the percentage of green pixels. I create a button to call the calc_green() function. When I run the code and click on the button, I get the error message: "TypeError: calc_green() missing 1 required positional argument: 'my_image' ". How can I solve this problem?

from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
import numpy as np

root = Tk()
root.title("Photo Analysis")
root.geometry('1360x765')
root.iconbitmap(r'icon.ico')

main_frame = Frame(root)
main_frame.pack(fill="both", expand=True)

def open():

    for widget in img_display_canvas.winfo_children():
        widget.destroy()

    global my_image
    filename = filedialog.askopenfilename(initialdir="/", title="Select A File", filetypes=(("all files", "*.*"), ("jpg files", "*.jpg"), ("png files", "*.png")))
    my_image = ImageTk.PhotoImage(Image.open(filename))
    my_image_label = Label(img_display_canvas, image=my_image).pack()
    return my_image

open_btn = Button(main_frame, text="Open File", padx=5, pady=2, font=('arial', 10, 'bold'), command=open)
open_btn.pack(pady=10)

img_display_canvas = Canvas(main_frame, width=800, height=450, bg='#d8d8d8')
img_display_canvas.pack()

def calc_green(my_image):
    img = Image.open(my_image)
    pixels = img.load()
    width, height = img.size
    total_green = 0
    for x in range(width):
        for y in range(height):
            rgb = pixels[x, y]
            if rgb[1] > rgb[0] and rgb[1] > rgb[2]:
                total_green = total_green + 1
    percent = (total_green / (width * height)) * 100
    print(str(percent) + " %")

calc_green_btn = Button(main_frame, text="Calc Green %", padx=5, pady=2, font=('arial', 10, 'bold'), bg='#009900', activebackground='#009900', command = calc_green)
calc_green_btn.pack()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • 2
    You have defined a parameter `my_image` in `calc_green(my_image)`, so without passing in `my_image` as an argument when calling the function(with the button), the function will give error. But looking at your code, you could just remove the parameter, as `my_image` is `global` in `open()` it will be used inside `calc_green` too, given that `open()` runs first. So: `def calc_green():` should do the trick. – Delrius Euphoria Feb 21 '21 at 11:32
  • Does https://stackoverflow.com/questions/9865936/what-are-the-limitations-of-callback-functions-associated-with-tkinter-traces help? – Karl Knechtel Feb 21 '21 at 11:40
  • Thank you, now is working with no problems. I have another question that you might be able to answer. When I run my code, I want the button that calls the calc_green() function to be hidden, and then, when I call the open() function and the image is displayed, the calc_green_btn to be shown. How can I do this? – Afonso Gamboa Feb 21 '21 at 17:43
  • Be careful defining functions with the same names as builtins; `open()` is a builtin that opens a file and returns a stream of its content. It is frequently used as a context manager. Redefining `open()` prevents you from using the builtin and is likely to lead to bugs in larger programs. – Michael Ruth Feb 21 '21 at 18:19

0 Answers0