Home > Back-end >  Why does it show that the variable "img" is not defined even though it is global?
Why does it show that the variable "img" is not defined even though it is global?

Time:12-17

This is a simple application to make a browse button to allow the user to choose an image and then show it, but when I tried to use the variable img or path (when defined as global) the following error shows up:

    cv2.imshow(" ",img)
  NameError: name 'img' is not defined

Code:

from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
from cv2 import *

root=Tk()
root.title("filter applicator")

def open():
   global my_image
   root.filename=filedialog.askopenfilename(
                        initialdir="/", title="select a file",
                        filetypes=(("png files","*.png"),("allfiles","*.*")))

   lbl=Label(root,text=root.filename).pack()
   my_image=ImageTk.PhotoImage(Image.open(root.filename))
   myimagelbl=Label(image=my_image).pack()
   #global path
   path=root.filename
   global img
   img=cv2.imread(path)

mybtn=Button(root,text="browse",command=open).pack()
cv2.imshow(" ",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
root.mainloop()

CodePudding user response:

You are trying to show the image before he pressed the "browse" button to select it. Make another button to allow the user to show the image after selecting it.

from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
import cv2
root=Tk()
root.title("filter applicator")

def open():
   global my_image
   root.filename=filedialog.askopenfilename(initialdir="/",
                                         title="select a file",
                                         filetypes=(("png files","*.png"),("allfiles","*.*")))

   lbl=Label(root,text=root.filename).pack()
   my_image=ImageTk.PhotoImage(Image.open(root.filename))
   myimagelbl=Label(image=my_image).pack()
   #global path
   path=root.filename
   global img
   img=cv2.imread(path)

def show_im():
    global img
    cv2.imshow(" ", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


mybtn=Button(root,text="browse",command=open).pack()
showbtn = Button(root,text="show",command=show_im).pack()

root.mainloop()

CodePudding user response:

I don't have cv2 install so couldn't really test this, but think it will solve the problem — including several others you haven't encountered yet. I've also made other changes like renaming your open() function browse() because the former is the nama of a Python built-in, as well as reformatting the code so it follows the PEP 8 - Style Guide for Python Code to make it more readable.

The problem with img not being defined is because it doesn't exist until your open() function is called. That just one of the problems with using global variables so I have tried to eliminate them whenever possible.

One common newbie tkinter mistake you made repeatably was to assign the value of the pack() widget method to a variable. That's a mistake because pack() always return None. In many (but not all) of those cases there was not even a need to assign anything to variable since it wasn't ever referenced again.

import cv2
from PIL import ImageTk, Image
import tkinter as tk
from tkinter.filedialog import askopenfilename

root = tk.Tk()
root.title("filter applicator")

def browse():
    filename = askopenfilename(initialdir="./", title="select a file",
                               filetypes=(("png files","*.png"),("allfiles","*.*")))
    if not filename:
        return  # User didn't select a file.

    tk.Label(root, text=filename).pack()
    my_image = ImageTk.PhotoImage(Image.open(filename))
    img_lbl = tk.Label(image=my_image)
    img_lbl.img = my_image  # Save reference to image.
    img_lbl.pack()

    img = cv2.imread(filename)
    show_image(img)

def show_image(img):
    cv2.imshow(" ", img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

tk.Button(root, text="Browse", command=browse).pack()

root.mainloop()
  • Related