import cv2
import tkinter as tk
from tkinter import messagebox
from datetime import datetime
from PIL import Image, ImageTk

import os
import pickle
import face_recognition

# Загрузка известных лиц
known_faces = pickle.load(open("known_faces.pkl", "rb"))

root = tk.Tk()
root.title("Face Recognition")

# Функция для обработки кнопки "Сделать снимок"
def capture_snapshot():
    global video_capture
    # Получение текущего кадра видео
    ret, frame = video_capture.read()
    # Поиск лиц на изображении
    face_locations = face_recognition.face_locations(frame)
    if len(face_locations) > 0:
        # Если на видео есть лицо, сохраняем снимок
        # Генерация уникального имени файла на основе времени
        now = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"snapshot_{now}.png"
        # Сохранение снимка в папку “database”
        cv2.imwrite(os.path.join("database", filename), frame)
        messagebox.showinfo("Snapshot", "Снимок сохранен")
    else:
        # Если на видео нет лица, выводим сообщение
        messagebox.showinfo("No Face", "На видео нет лица")

# Функция для обработки кнопки "Проверить"
def check_faces():
    global video_capture
    # Получение текущего кадра видео
    ret, frame = video_capture.read()

    # Поиск лиц на изображении
    face_locations = face_recognition.face_locations(frame)
    face_encodings = face_recognition.face_encodings(frame, face_locations)

    # Инициализация списка для хранения имен лиц на изображении
    face_names = []

    # Проход по лицам на изображении
    for face_encoding in face_encodings:
        # Сравнение лица с известными лицами
        matches = face_recognition.compare_faces(known_faces["encodings"], face_encoding)
        name = "Unknown"

        # Поиск совпадений
        if True in matches:
            matched_indexes = [i for (i, b) in enumerate(matches) if b]
            counts = {}

            # Подсчет совпадений
            for i in matched_indexes:
                name = known_faces["names"][i]
                counts[name] = counts.get(name, 0) + 1

            # Получение имени с наибольшим количеством совпадений
            name = max(counts, key=counts.get)

        face_names.append(name)

    # Проверка, есть ли человек из базы данных на видео
    if any(name != "Unknown" for name in face_names):
        messagebox.showinfo("Face Recognition", "На видео есть человек из базы данных")
    else:
        messagebox.showinfo("Face Recognition", "На видео нет человека из базы данных")

# Инициализация видеокамеры
video_capture = cv2.VideoCapture(0)

# Функция для обновления видео в окне Tkinter
def update_video():
    # Получение текущего кадра видео
    ret, frame = video_capture.read()
    if ret:
        # Конвертация цветового пространства BGR в RGB
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        # Создание изображения Tkinter из массива numpy
        img = Image.fromarray(frame_rgb)
        imgtk = ImageTk.PhotoImage(image=img)
        # Обновление изображения в окне
        video_label.imgtk = imgtk
        video_label.configure(image=imgtk)
    video_label.after(10, update_video)

# Создание окошка для отображения видео
video_label = tk.Label(root)
video_label.pack()

# Создание кнопки "Сделать снимок"
snapshot_button = tk.Button(root, text="Сделать снимок", command=capture_snapshot)
snapshot_button.pack()

# Создание кнопки "Проверить"
check_button = tk.Button(root, text="Проверить", command=check_faces)
check_button.pack()

# Обновление видео в окне
update_video()

# Запуск главного цикла программы
root.mainloop()

# Освобождение ресурсов
video_capture.release()
cv2.destroyAllWindows()

как сделать форму регистрации чтобы была кнопка «новый пользователь» чтобы  открывалось дополнительное окно tinker и пользователь мог ввести свое имя и логин и сохранить свое лицо в базу данных, и в базу данных сохранялась картинка с указанным пользователем логином(для логина добавить ограничения соответствующие ограничениям названия файла в windows), а также предложить пользователю ввести пароль, если не получиться распознать лицо пользователя. Пароль и логин и имя сохраняются в файле который хранится также в папке database. (соответсвенно нужно проверять наличия существующего пользователя с таким же логином паролем или лицом)