Advertisement
here2share

# tk_face_recog.py

Jul 11th, 2024
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.06 KB | None | 0 0
  1. # tk_face_recog.py ZZZ
  2.  
  3. import os
  4. import random
  5. import string
  6. from tkinter import Tk, simpledialog, messagebox, filedialog, Button, Frame, Label, Scrollbar, Listbox, Toplevel, VERTICAL
  7. from PIL import Image, ImageOps, ImageTk
  8. import math
  9.  
  10. def browse_for_directory():
  11.     return filedialog.askdirectory(initialdir=current_directory, title='Select Directory')
  12.  
  13. def browse_for_file():
  14.     return filedialog.askopenfilename(initialdir=current_directory, title='Select Training Data File')
  15.  
  16. def get_images_and_labels(image_directory, subdirs, label_mapping):
  17.     image_paths = []
  18.     for subdir in subdirs:
  19.         path = os.path.join(image_directory, subdir)
  20.         for filename in os.listdir(path):
  21.             image_paths.append(os.path.join(path, filename))
  22.    
  23.     images = []
  24.     labels = []
  25.     for image_path in image_paths:
  26.         img = Image.open(image_path).convert('L')
  27.         img = ImageOps.fit(img, (100, 100), Image.ANTIALIAS)
  28.         image = list(img.getdata())
  29.         subdir = os.path.basename(os.path.dirname(image_path))
  30.         label = label_mapping[subdir]
  31.         images.append(image)
  32.         labels.append(label)
  33.     return images, labels
  34.  
  35. def train_recognizer(image_directory, subdirs, label_mapping):
  36.     images, labels = get_images_and_labels(image_directory, subdirs, label_mapping)
  37.     recognizer = {}
  38.     for i, label in enumerate(labels):
  39.         recognizer[label] = images[i]
  40.     return recognizer
  41.  
  42. def euclidean_distance(img1, img2):
  43.     return math.sqrt(sum((img1[i] - img2[i]) ** 2 for i in range(len(img1))))
  44.  
  45. def show_image(image_path, image_listbox, listbox_side):
  46.     global top
  47.     try:
  48.         top.destroy()
  49.     except:
  50.         pass
  51.     top = Toplevel(root)
  52.     img = Image.open(image_path)
  53.     width, height = img.size
  54.     ratio = height / width
  55.     new_height = int(500 * ratio)
  56.     img = img.resize((500, new_height), Image.ANTIALIAS)
  57.     img = ImageTk.PhotoImage(img)
  58.     panel = Label(top, image=img)
  59.     panel.image = img
  60.     panel.place(x=0, y=0)
  61.  
  62.     screen_width = root.winfo_screenwidth()
  63.     screen_height = root.winfo_screenheight()
  64.     window_width = 500
  65.     window_height = new_height
  66.  
  67.     if listbox_side == 'left':
  68.         x = 640
  69.     else:
  70.         x = 40
  71.  
  72.     y = -30
  73.     top.geometry(f"{window_width}x{window_height}+{x}+{y}")
  74.     image_listbox.bind("<Leave>", lambda event: top.destroy())
  75.     top.bind("<Button-1>", lambda event: top.destroy())
  76.  
  77. def browse_images():
  78.     global image_directory
  79.     image_directory = browse_for_directory()
  80.     update_status("Selected image directory: " + image_directory)
  81.     load_image_list()
  82.  
  83. def train_data():
  84.     global recognizer, image_directory
  85.     if not image_directory:
  86.         update_status("Please select an image directory first.")
  87.         return
  88.    
  89.     training_data_path = os.path.join(current_directory, "training_data", "training_data.txt")
  90.     if not os.path.exists(training_data_path):
  91.         create_training_data = messagebox.askyesno("Create Training Data", "Training data not found. Would you like to create a new training_data folder and training_data.txt file?")
  92.         if create_training_data:
  93.             os.makedirs(os.path.join(current_directory, "training_data"), exist_ok=True)
  94.             with open(training_data_path, 'w') as f:
  95.                 f.write("")  # Create an empty training_data.txt file
  96.             update_status("Created training_data folder and training_data.txt file.")
  97.         else:
  98.             update_status("Training data not found. Training aborted.")
  99.             return
  100.  
  101.     recognizer = train_recognizer(image_directory, subdirs, label_mapping)
  102.     load_nearest_images()
  103.  
  104. def update_status(message):
  105.     status_label.config(text=message)
  106.  
  107. def load_image_list():
  108.     global image_directory
  109.     image_listbox.delete(0, 'end')
  110.     for filename in os.listdir(image_directory):
  111.         if '.' in filename:
  112.             image_listbox.insert('end', filename)
  113.  
  114. def load_nearest_images():
  115.     global recognizer, image_directory
  116.     if not recognizer:
  117.         update_status("Please load the training data first.")
  118.         return
  119.     image_files = [f for f in os.listdir(image_directory) if f.endswith('.jpg') or f.endswith('.png')]
  120.     distances = []
  121.     for image_file in image_files:
  122.         image_path = os.path.join(image_directory, image_file)
  123.         img = Image.open(image_path).convert('L')
  124.         img = ImageOps.fit(img, (100, 100), Image.ANTIALIAS)
  125.         img_data = list(img.getdata())
  126.         min_diff = float('inf')
  127.         for image in recognizer.values():
  128.             diff = euclidean_distance(img_data, image)
  129.             if diff < min_diff:
  130.                 min_diff = diff
  131.         distances.append((min_diff, image_file))
  132.     distances.sort()
  133.     nearest_images = [image_file for _, image_file in distances[:2500]]
  134.     nearest_listbox.delete(0, 'end')
  135.     for filename in nearest_images:
  136.         nearest_listbox.insert('end', filename)
  137.  
  138. def on_image_select(event):
  139.     selected_image = image_listbox.get(image_listbox.curselection())
  140.     image_path = os.path.join(image_directory, selected_image)
  141.     show_image(image_path, image_listbox, 'left')
  142.  
  143. def on_nearest_select(event):
  144.     selected_image = nearest_listbox.get(nearest_listbox.curselection())
  145.     image_path = os.path.join(image_directory, selected_image)
  146.     show_image(image_path, nearest_listbox, 'right')
  147.  
  148. root = Tk()
  149. root.title("Face Recognition")
  150. root.geometry("1200x640+10+10")
  151.  
  152. frame = Frame(root)
  153. frame.pack(side='top', fill='x', padx=10, pady=10)
  154.  
  155. browse_button = Button(frame, text="Select Image Directory", command=browse_images)
  156. browse_button.pack(side='left', padx=5)
  157.  
  158. load_button = Button(frame, text="Load Training Data", command=browse_for_file)
  159. load_button.pack(side='left', padx=5)
  160.  
  161. train_button = Button(frame, text="Train Data", command=train_data)
  162. train_button.pack(side='left', padx=5)
  163.  
  164. status_label = Label(frame, text="Status: Waiting for input")
  165. status_label.pack(side='left', padx=5)
  166.  
  167. image_frame = Frame(root)
  168. image_frame.pack(side='left', fill='y', padx=10, pady=10)
  169.  
  170. image_listbox = Listbox(image_frame, width=80)
  171. image_listbox.pack(side='left', fill='y')
  172. image_listbox_scrollbar = Scrollbar(image_frame, orient=VERTICAL, command=image_listbox.yview)
  173. image_listbox_scrollbar.pack(side='right', fill='y')
  174. image_listbox.config(yscrollcommand=image_listbox_scrollbar.set)
  175.  
  176. nearest_frame = Frame(root)
  177. nearest_frame.pack(side='right', fill='y', padx=10, pady=10)
  178.  
  179. nearest_listbox = Listbox(nearest_frame, width=80)
  180. nearest_listbox.pack(side='left', fill='y')
  181. nearest_listbox_scrollbar = Scrollbar(nearest_frame, orient=VERTICAL, command=nearest_listbox.yview)
  182. nearest_listbox_scrollbar.pack(side='right', fill='y')
  183. nearest_listbox.config(yscrollcommand=nearest_listbox_scrollbar.set)
  184.  
  185. image_listbox.bind('<<ListboxSelect>>', on_image_select)
  186. nearest_listbox.bind('<<ListboxSelect>>', on_nearest_select)
  187.  
  188. current_directory = os.path.dirname(os.path.abspath(__file__))
  189. image_directory = ""
  190. training_data_file = ""
  191. recognizer = None
  192. subdirs = []
  193. label_mapping = {}
  194. top = None
  195.  
  196. root.mainloop()
  197.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement