diff --git a/notebooks/app/FDJ.jpg b/notebooks/app/FDJ.jpg new file mode 100644 index 0000000..ace1b2d Binary files /dev/null and b/notebooks/app/FDJ.jpg differ diff --git a/notebooks/app/FastMtcnn.py b/notebooks/app/FastMtcnn.py new file mode 100644 index 0000000..1a6b7ac --- /dev/null +++ b/notebooks/app/FastMtcnn.py @@ -0,0 +1,79 @@ +import cv2 +from facenet_pytorch import MTCNN +from PIL import Image +import torch +from imutils.video import FileVideoStream +import cv2 +import time +from catboost import CatBoostClassifier +from tqdm.notebook import tqdm +from deepface import DeepFace +import pandas as pd +import pickle +import numpy as np + +device = 'cuda' if torch.cuda.is_available() else 'cpu' + + +class FastMTCNN(object): + """Fast MTCNN implementation.""" + + def __init__(self, stride, resize=1, *args, **kwargs): + """Constructor for FastMTCNN class. + + Arguments: + stride (int): The detection stride. Faces will be detected every `stride` frames + and remembered for `stride-1` frames. + + Keyword arguments: + resize (float): Fractional frame scaling. [default: {1}] + *args: Arguments to pass to the MTCNN constructor. See help(MTCNN). + **kwargs: Keyword arguments to pass to the MTCNN constructor. See help(MTCNN). + """ + self.stride = stride + self.resize = resize + self.mtcnn = MTCNN(*args, **kwargs) + self.catboost_model_usa = CatBoostClassifier() + self.catboost_model_usa.load_model("../catboost_usa.cbm") + with open('../model/saved_dictionary.pkl', 'rb') as f: + self.name_usa = pickle.load(f) + + def __call__(self, frames): + """Detect faces in frames using strided MTCNN.""" + if self.resize != 1: + frames = [ + cv2.resize(f, (int(f.shape[1] * self.resize), int(f.shape[0] * self.resize))) + for f in frames + ] + + boxes, probs = self.mtcnn.detect(frames[::self.stride]) + dicter3 = {} + faces = [] + names = {} + all_x = pd.DataFrame() + for i, frame in enumerate(frames[::self.stride]): + box_ind = int(i / self.stride) + if boxes[box_ind] is None: + continue + for box in boxes[box_ind]: + box = [int(b) for b in box] + faces.append(frame[box[1]:box[3], box[0]:box[2]]) + image = frame[box[1]:box[3], box[0]:box[2]] + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + embedding = DeepFace.represent(image, model_name='Facenet', enforce_detection=False) + try: + ebd = embedding[0]["embedding"] + except: + continue + dicter3[1] = ebd + data_usa = pd.DataFrame.from_dict(dicter3.items()) + data_usa.rename(columns={0: "id", 1: "embd"}, inplace=True, errors="ignore") + new_cols = pd.DataFrame(data_usa['embd'].apply(pd.Series)) + df_usa = pd.concat([data_usa, new_cols], axis=1) + df_usa.drop(["embd"], axis=1, inplace=True, errors="ignore") + df_usa["id"] = df_usa["id"].apply(lambda x: str(x)[:str(x).find("_")]) + y, X = df_usa["id"], df_usa.drop(["id"], axis=1) + all_x = pd.concat([all_x, X], axis=0) + result = self.catboost_model_usa.predict(all_x) + vals, counts = np.unique(result, return_counts=True) + return vals[np.argmax(counts)] \ No newline at end of file diff --git a/notebooks/app/PredictServer.py b/notebooks/app/PredictServer.py new file mode 100644 index 0000000..d1d4059 --- /dev/null +++ b/notebooks/app/PredictServer.py @@ -0,0 +1,117 @@ +import pickle +import customtkinter as ctk +import os +import cv2 +from PIL import Image, ImageTk +from deepface import DeepFace +from mtcnn import MTCNN +from catboost import CatBoostClassifier +import pandas as pd +import numpy as np + +class Server(ctk.CTkFrame): + def __init__(self, master): + super().__init__(master) + self.counter = 0 + self.storage_name: str + self.grid_columnconfigure(0, weight=1) + self.detector = MTCNN() + import socket + self.s = socket.socket() + host = "192.168.120.240" + port = 12345 + self.s.bind((host, port)) + self.s.listen(5) + self.catboost_model_usa = CatBoostClassifier() + self.catboost_model_usa.load_model("../catboost_usa.cbm") + with open('../model/saved_dictionary.pkl', 'rb') as f: + self.name_usa = pickle.load(f) + # self.grid_rowconfigure(0, weight=1) + self.label = ctk.CTkLabel(self, text="Server", fg_color="blue", text_color="white") + self.label.grid(row=0, column=0, sticky="ew") + self.button_start_predict = ctk.CTkButton(self, text="Get photo from server", command=self.__start_predict) + self.button_start_predict.grid(row=1, column=0, pady=10, sticky="ew") + + + def __open_file_dialog(self): + root = ctk.CTk() + root.withdraw() + file_path = ctk.filedialog.askdirectory(title='Choose image dataset') + if file_path != '': + root.destroy() + self.storage_name = file_path + self.iterator = iter(os.listdir(self.storage_name)) + return file_path + def __start_predict(self): + while True: + c = 0 + con, addr = self.s.accept() + with open('FDJ.jpg', 'wb') as f: + while True: + c+=1 + print(1) + data = con.recv(65536) + if c >= 3: + f.write(data) + break + if not data: + f.write(data) + break + break + #break + + f.write(data) + + break + + #break + + print("break") + break + if self.counter > 0: + self.label.destroy() + self.counter+=1 + filename = 'FDJ.jpg' + dicter3 = {} + if filename.endswith("png") or filename.endswith("jpg"): + print(filename) + img = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2RGB) + img = cv2.resize(img, (1080, 720)) + detections = self.detector.detect_faces(img) + if len(detections) > 1: + print("AAAAAAAAA") + for detection in detections: + confidence = detection["confidence"]# + if confidence > 0.9: + x, y, w, h = detection["box"] + detected_face = img[int(y):int(y + h), int(x):int(x + w)]## + image = cv2.rectangle(img, (int(x), int(y)), (int(x+w), int(y+h)), (255, 0, 0), 2) + embedding = DeepFace.represent(detected_face, model_name='Facenet', enforce_detection=False) + ebd = embedding[0]["embedding"] + dicter3[1] = ebd + data_usa = pd.DataFrame.from_dict(dicter3.items()) + data_usa.rename(columns={0: "id", 1: "embd"}, inplace=True, errors="ignore") + new_cols = pd.DataFrame(data_usa['embd'].apply(pd.Series)) + df_usa = pd.concat([data_usa, new_cols], axis=1) + df_usa.drop(["embd"], axis=1, inplace=True, errors="ignore") + #df_usa["id"] = df_usa["id"].apply(lambda x: str(x)[:str(x).find("_")]) + y, X = df_usa["id"], df_usa.drop(["id"], axis=1) + result = self.catboost_model_usa.predict(X) + index_usa = result[0][0] + print(result) + string = self.name_usa[result[0][0]] + encoded_string = string.encode('utf-8') # Кодируем строку в UTF-8 + binary_representation = ''.join(format(byte, '08b') for byte in encoded_string) + con.send(binary_representation.encode('utf-8')) + con.close() + print(self.name_usa[result[0][0]]) + for images in os.listdir(f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_usa//{index_usa}'): + image_usa = cv2.imread(os.path.join(f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_usa//{index_usa}', images)) + break + image[0:128, 0:128] = cv2.resize(cv2.cvtColor(image_usa, cv2.COLOR_BGR2RGB), (128,128)) + #print(np.argmax(result[0], axis=0)) + #print(len(result[0])) + self.image = Image.fromarray(image) + self.image_tk = ctk.CTkImage(self.image, size=(self.image.width, self.image.height)) + self.label = ctk.CTkLabel(self, image=self.image_tk, text=self.name_usa[result[0][0]], text_color="red") + self.label.grid(row=3, column=0, pady=10, sticky="ew") diff --git a/notebooks/app/Predict_photo.py b/notebooks/app/Predict_photo.py new file mode 100644 index 0000000..21990b6 --- /dev/null +++ b/notebooks/app/Predict_photo.py @@ -0,0 +1,88 @@ +import pickle +import customtkinter as ctk +import os +import cv2 +from PIL import Image +from deepface import DeepFace +from mtcnn import MTCNN +from catboost import CatBoostClassifier +import pandas as pd + + +class Predict(ctk.CTkFrame): + def __init__(self, master): + super().__init__(master) + self.counter = 0 + self.storage_name: str + self.grid_columnconfigure(0, weight=1) + self.detector = MTCNN() + self.catboost_model_usa = CatBoostClassifier() + self.catboost_model_usa.load_model("../catboost_usa.cbm") + self.catboost_model_ussr = CatBoostClassifier() + self.catboost_model_ussr.load_model("../catboost_ussr.cbm") + with open('../model/saved_dictionary.pkl', 'rb') as f: + self.name_usa = pickle.load(f) + with open('../model/saved_dictionary_russia.pkl', 'rb') as f: + self.name_ussr = pickle.load(f) + self.label = ctk.CTkLabel(self, text="Photo", fg_color="blue", text_color="white") + self.label.grid(row=0, column=0, sticky="ew") + self.button_get_dir = ctk.CTkButton(self, text="Choose folder", command=self.__open_file_dialog) + self.button_get_dir.grid(row=1, column=0, pady=10, sticky="ew") + self.button_start_predict = ctk.CTkButton(self, text="Start predict", command=self.__start_predict) + self.button_start_predict.grid(row=2, column=0, pady=10, sticky="ew") + + def __open_file_dialog(self): + root = ctk.CTk() + root.withdraw() + file_path = ctk.filedialog.askdirectory(title='Choose image dataset') + if file_path != '': + root.destroy() + self.storage_name = file_path + self.iterator = iter(os.listdir(self.storage_name)) + return file_path + + def __start_predict(self): + if self.counter > 0: + self.label.destroy() + self.counter+=1 + filename = next(self.iterator) + dicter3 = {} + if filename.endswith("png") or filename.endswith("jpg"): + print(filename) + img = cv2.cvtColor(cv2.imread(os.path.join(self.storage_name, filename)), cv2.COLOR_BGR2RGB) + img = cv2.resize(img, (1080, 720)) + detections = self.detector.detect_faces(img) + if len(detections) > 1: + print(f'len detection = {len(detections)}') + for detection in detections: + confidence = detection["confidence"]# + if confidence > 0.9: + x, y, w, h = detection["box"] + detected_face = img[int(y):int(y + h), int(x):int(x + w)]## + image = cv2.rectangle(img, (int(x), int(y)), (int(x+w), int(y+h)), (255, 0, 0), 2) + embedding = DeepFace.represent(detected_face, model_name='Facenet', enforce_detection=False) + ebd = embedding[0]["embedding"] + dicter3[1] = ebd + data_usa = pd.DataFrame.from_dict(dicter3.items()) + data_usa.rename(columns={0: "id", 1: "embd"}, inplace=True, errors="ignore") + new_cols = pd.DataFrame(data_usa['embd'].apply(pd.Series)) + df_usa = pd.concat([data_usa, new_cols], axis=1) + df_usa.drop(["embd"], axis=1, inplace=True, errors="ignore") + X = df_usa.drop(["id"], axis=1) + result = self.catboost_model_usa.predict(X) + result_ussr = self.catboost_model_ussr.predict(X) + index_usa = result[0][0] + index_ussr = result_ussr[0][0] + for images in os.listdir(f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_usa//{index_usa}'): + image_usa = cv2.imread(os.path.join(f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_usa//{index_usa}', images)) + break + for images in os.listdir(f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_ussr_russia//{index_ussr}'): + image_ussr = cv2.imread(os.path.join(f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_ussr_russia//{index_ussr}', images)) + break + image[0:128, 0:128] = cv2.resize(cv2.cvtColor(image_usa, cv2.COLOR_BGR2RGB), (128,128)) + image[0:128, 138:266] = cv2.resize(cv2.cvtColor(image_ussr, cv2.COLOR_BGR2RGB), (128,128)) + self.image = Image.fromarray(image) + self.image_tk = ctk.CTkImage(self.image, size=(self.image.width, self.image.height)) + self.label = ctk.CTkLabel(self, image=self.image_tk, text=self.name_usa[result[0][0]], text_color="red") + self.label.grid(row=3, column=0, pady=10, sticky="ew") + diff --git a/notebooks/app/Predict_video.py b/notebooks/app/Predict_video.py new file mode 100644 index 0000000..93bda6d --- /dev/null +++ b/notebooks/app/Predict_video.py @@ -0,0 +1,87 @@ +import pickle +import customtkinter as ctk +import os +from mtcnn import MTCNN +from catboost import CatBoostClassifier +from facenet_pytorch import MTCNN +from PIL import Image +import torch +import cv2 +import time +from FastMtcnn import FastMTCNN +import threading + +device = 'cuda' if torch.cuda.is_available() else 'cpu' + + +class PredictV(ctk.CTkFrame): + def __init__(self, master): + super().__init__(master) + self.counter = 0 + self.storage_name: str + self.grid_columnconfigure(0, weight=1) + self.detector = MTCNN() + self.catboost_model_usa = CatBoostClassifier() + self.catboost_model_usa.load_model("../catboost_usa.cbm") + self.fast_mtcnn = FastMTCNN( + stride=32, + resize=1, + margin=14, + factor=0.6, + keep_all=True, + device=device + ) + self.catboost_model_usa.load_model("../catboost_usa.cbm") + with open('../model/saved_dictionary.pkl', 'rb') as f: + self.name_usa = pickle.load(f) + self.label = ctk.CTkLabel(self, text="Video", fg_color="blue", text_color="white") + self.label.grid(row=0, column=0, sticky="ew") + self.button_start_predict = ctk.CTkButton(self, text="Start predict", command=self.run_detection) + self.button_start_predict.grid(row=1, column=0, pady=10, sticky="ew") + + def __open_file_dialog(self): + root = ctk.CTk() + root.withdraw() + file_path = ctk.filedialog.askdirectory(title='Choose image dataset') + if file_path != '': + root.destroy() + self.storage_name = file_path + self.iterator = iter(os.listdir(self.storage_name)) + return file_path + + def run_detection(self): + frames = [] + batch_size = 256 + cap = cv2.VideoCapture(0) + self.image_usa = cv2.resize(cap.read()[1], (1080, 720)) + while True: + frame = cv2.resize(cap.read()[1], (1080, 720)) + frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + frames.append(frame) + im_h = cv2.hconcat([frame, self.image_usa]) + cv2.imshow("tester", im_h) + if cv2.waitKey(1) == 27: + break + + if len(frames) >= batch_size: + index_usa = self.fast_mtcnn(frames) + frames = [] + def set_image_all(index_usa): + print(index_usa) + for images in os.listdir( + f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_usa//{index_usa}'): + self.image_usa = cv2.imread( + os.path.join(f'C://Users//fatik//PycharmProjects//UfaHack2024//data//actors_usa//{index_usa}', images)) + self.image_usa = cv2.resize(self.image_usa, (1080, 720)) + break + def set_image(): + self.image = Image.fromarray(self.image_usa) + self.image_tk = ctk.CTkImage(self.image, size=(self.image.width, self.image.height)) + self.label_image = ctk.CTkLabel(self, image=self.image_tk, text=self.name_usa[index_usa], text_color="red") + self.label_image.grid(row=2, column=0, pady=10, sticky="ew") + thread = threading.Thread(target=set_image) + thread.start() + + target1 = threading.Thread(target=set_image_all, args=(index_usa,)) + target1.start() + diff --git a/notebooks/app/Start.py b/notebooks/app/Start.py new file mode 100644 index 0000000..e98bac2 --- /dev/null +++ b/notebooks/app/Start.py @@ -0,0 +1,19 @@ +import customtkinter +from Predict_photo import Predict +from Predict_video import PredictV + + +class Start(customtkinter.CTk): + def __init__(self): + super().__init__() + customtkinter.set_appearance_mode("dark") + self.title("Face recognition system") + self.grid_columnconfigure(0, weight=1) + self.grid_columnconfigure(1, weight=1) + self.grid_rowconfigure(0, weight=1) + self.grid_rowconfigure(1, weight=1) + self.grid_rowconfigure(2, weight=1) + self.predict = Predict(self) + self.predict.grid(row=0, column=0, sticky="nswe", pady=5) + self.video= PredictV(self) + self.video.grid(row=0, column=1, sticky="nsew", pady=5) diff --git a/notebooks/app/__pycache__/FastMtcnn.cpython-310.pyc b/notebooks/app/__pycache__/FastMtcnn.cpython-310.pyc new file mode 100644 index 0000000..caa296b Binary files /dev/null and b/notebooks/app/__pycache__/FastMtcnn.cpython-310.pyc differ diff --git a/notebooks/app/__pycache__/PredictServer.cpython-310.pyc b/notebooks/app/__pycache__/PredictServer.cpython-310.pyc new file mode 100644 index 0000000..7f6ff0e Binary files /dev/null and b/notebooks/app/__pycache__/PredictServer.cpython-310.pyc differ diff --git a/notebooks/app/__pycache__/Predict_photo.cpython-310.pyc b/notebooks/app/__pycache__/Predict_photo.cpython-310.pyc new file mode 100644 index 0000000..2e80963 Binary files /dev/null and b/notebooks/app/__pycache__/Predict_photo.cpython-310.pyc differ diff --git a/notebooks/app/__pycache__/Predict_video.cpython-310.pyc b/notebooks/app/__pycache__/Predict_video.cpython-310.pyc new file mode 100644 index 0000000..b59f922 Binary files /dev/null and b/notebooks/app/__pycache__/Predict_video.cpython-310.pyc differ diff --git a/notebooks/app/__pycache__/Start.cpython-310.pyc b/notebooks/app/__pycache__/Start.cpython-310.pyc new file mode 100644 index 0000000..9144074 Binary files /dev/null and b/notebooks/app/__pycache__/Start.cpython-310.pyc differ diff --git a/notebooks/app/main.py b/notebooks/app/main.py new file mode 100644 index 0000000..e030523 --- /dev/null +++ b/notebooks/app/main.py @@ -0,0 +1,23 @@ +from tkinter import messagebox +from Start import Start +import platform + + +def on_closing(): + if messagebox.askokcancel("Подтверждение закрытия", "Вы уверены, что хотите закрыть приложение?"): + app.destroy() + + +app = Start() +app.geometry(f"{app.winfo_screenwidth()}x{app.winfo_screenheight()}") +app.protocol("WM_DELETE_WINDOW", on_closing) +app.mainloop() + +system = platform.system() +if system == "Windows": + app.after(0, lambda: app.state('zoomed')) +elif system == "Linux": + app.attributes("-fullscreen", True) +app.bind("", lambda event: app.attributes("-fullscreen", + not app.attributes("-fullscreen"))) +app.bind("", lambda event: app.attributes("-fullscreen", False))