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


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

def open_registration_form():
    registration_window = tk.Toplevel(root)
    registration_window.title("Регистрация")

    # Функция для обработки нажатия кнопки “Зарегистрироваться”
    def register_user():
        name = name_entry.get()
        username = username_entry.get()
        password = password_entry.get()

        # Проверка наличия пользователя с таким же логином
        if username in known_faces["names"]:
            messagebox.showerror("Ошибка", "Пользователь с таким логином уже существует")
            return

        # Получение текущего кадра видео
        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_{username}_{now}.png"
            # Сохранение снимка в папку “database”
            cv2.imwrite(os.path.join("database", filename), frame)

           

            messagebox.showinfo("Регистрация", "Пользователь успешно зарегистрирован")
            registration_window.destroy()
        else:
            # Если на видео нет лица, выводим сообщение
            messagebox.showinfo("“Ошибка”", "“На видео нет лица”")

    # Создание поля для ввода имени пользователя
    name_label = tk.Label(registration_window, text="“Имя”")
    name_label.pack()
    name_entry = tk.Entry(registration_window)
    name_entry.pack()

    # Создание поля для ввода логина пользователя
    username_label = tk.Label(registration_window, text="Логин")
    username_label.pack()
    username_entry = tk.Entry(registration_window)
    username_entry.pack()

    # Создание поля для ввода пароля пользователя
    password_label = tk.Label(registration_window, text="“Пароль”")
    password_label.pack()
    password_entry = tk.Entry(registration_window, show="“*”")
    password_entry.pack()

    # Создание кнопки “Зарегистрироваться”
    register_button = tk.Button(registration_window, text="“Зарегистрироваться”", command=register_user)
    register_button.pack()

# Функция для обработки кнопки "Сделать снимок"
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()

исправь чтобы видео с веб камеры находилось внтри окна и были кнопки которые делали бы снимок видео и добаваляли снимок в папку database
а потом рядом была еще одна кнока которая проверяла есть ли человек из database на видео


сделай в коде так чтобы при нажатии кнопки сохраняющей человека в базу данных, программа перед этим проверяла, если ли на видео лицо, и если есть, то сохраняла снимок

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