-1

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()
martineau
  • 119,623
  • 25
  • 170
  • 301
  • I think you need to assign it first in the global scope – Danny Raufeisen Dec 16 '21 at 22:27
  • 5
    `img` is defined inside `open()`, but `open()` hasn't been called yet. It will be called when the button is pressed. – khelwood Dec 16 '21 at 22:28
  • 1
    okay but the function open() was not called beforehead – Danny Raufeisen Dec 16 '21 at 22:31
  • 3
    By the way, [`open`](https://docs.python.org/3/library/functions.html#open) is the name of a built-in function. You should probably call your function something else. – khelwood Dec 16 '21 at 22:32
  • You have already used a label to show the image (although it has the issue of this [question](https://stackoverflow.com/questions/16424091/why-does-tkinter-image-not-show-up-if-created-in-a-function), but it is easy to fix), why do you show it again in another window using `opencv`? – acw1668 Dec 17 '21 at 01:14
  • @acw1668 this is actually a part of my code so the purpose is not clear in the question. – Aya Ibrahim Dec 17 '21 at 16:16

2 Answers2

1

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()
user23952
  • 578
  • 3
  • 10
1

I don't have cv2 installed 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()
martineau
  • 119,623
  • 25
  • 170
  • 301