Reputation: 7
I wrote a program for facial recognition and now I have to make a GUI for it. What I need to do is to display 5 images of recognized person. But I can only display one of them. The others are shown empty. Here is the code:
root = Tk()
root.title("Test state")
def train_button():
os.system('python3 extract_embeddings.py --dataset dataset --embeddings output/embeddings.pickle --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7')
os.system('python3 train_model.py --embeddings output/embeddings.pickle --recognizer output/recognizer.pickle --le output/le.pickle')
messagebox.showinfo("INFO","Training completed")
def select_photo():
global my_image
root.filename = filedialog.askopenfilename(initialdir="test",title ="Select a photo",filetypes=(("all files","*.*"),("png files","*.png"),("jpeg files","*.jpeg")))
output = subprocess.check_output("python3 recognize.py --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 --recognizer output/recognizer.pickle --le output/le.pickle --image "+root.filename, shell=True)
output = output.decode('utf-8')
pic_name = output.split('\n')[0]
my_image = ImageTk.PhotoImage(Image.open("images/"+pic_name+"/"+pic_name+"1.jpeg"))
my_image_label = Label(image = my_image).grid(row = 1 ,column = 0)
name_label = Label(text = pic_name).grid(row=2,column=0)
my_image1 = ImageTk.PhotoImage(Image.open("images/"+pic_name+"/"+pic_name+"2.jpeg"))
my_image_label1 = Label(image = my_image1).grid(row =1 ,column=1)
my_image2 = ImageTk.PhotoImage(Image.open("images/"+pic_name+"/"+pic_name+"3.jpeg"))
my_image_label2 = Label(image = my_image2).grid(row = 1,column = 2)
button1 = Button(root,text = "Train" , command = train_button).grid(row=0 ,column=0)
button2 = Button(root,text = "Recognise from image", command = select_photo).grid(row = 0 ,column=1)
root.mainloop()
This is how the program shows images Resulting program
Thank you for your time
Upvotes: 0
Views: 6816
Reputation: 142651
It is bug in PhotoImage
which removes image when it is assigned to local variable in function.
You have to assing it to global variable (it can be list if you have many images) or assign to widgets which you use to display it - label.photo = image
I can test it but here is version which uses label.photo = image
to resolve this problem
It also uses for
-loop to create labels and keep them on list.
But when you use label.photo = image
then list is not necessary. List is only useful to access labels to remove old labels before you create new labels.
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import filedialog
# --- functions ---
def train_button():
os.system('python3 extract_embeddings.py --dataset dataset --embeddings output/embeddings.pickle --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7')
os.system('python3 train_model.py --embeddings output/embeddings.pickle --recognizer output/recognizer.pickle --le output/le.pickle')
messagebox.showinfo("INFO","Training completed")
def select_photo():
#global all_labels
root.filename = filedialog.askopenfilename(initialdir="test", title ="Select a photo", filetypes=(("all files","*.*"),("png files","*.png"),("jpeg files","*.jpeg")))
output = subprocess.check_output("python3 recognize.py --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 --recognizer output/recognizer.pickle --le output/le.pickle --image "+root.filename, shell=True)
output = output.decode('utf-8')
pic_name = output.split('\n')[0]
# remove previous labels
for label in all_labels:
label.destroy()
for number in range(3):
#filename = f"images/{pic_name}/{pic_name}{number+1}.jpeg" # f-string (Python 3.6+)
filename = "images/{}/{}{}.jpeg".format(pic_name, pic_name, number+1) # (Python 2.7, 3.0+)
image = ImageTk.PhotoImage(Image.open(filename))
label = tk.Label(image=image)
label.photo = image # assign to class variable to resolve problem with bug in `PhotoImage`
label.grid(row=1, column=number)
all_labels.append(label)
# --- main ---
all_labels = []
root = tk.Tk()
button1 = tk.Button(root, text="Train", command=train_button)
button1.grid(row=0, column=0)
button2 = tk.Button(root, text="Recognise from image", command=select_photo)
button2.grid(row=0, column=1)
root.mainloop()
Upvotes: 1