import json import zipfile import numpy as np import cv2 import os import gradio as gr from deepface import DeepFace from ultralytics import YOLO import urllib.request with open("config.json", "r") as f: config = json.load(f) FACE_DIST_TRESH = config['FACE_DIST_TRESH'] FACE_DET_TRESH = config['FACE_DET_TRESH'] YOLO_WEIGHTS_URL = config['YOLO_WEIGHTS_URL'] yolo_weights_filename = os.path.basename(YOLO_WEIGHTS_URL) if not os.path.exists(yolo_weights_filename): urllib.request.urlretrieve(YOLO_WEIGHTS_URL, yolo_weights_filename) model = YOLO(yolo_weights_filename) def find_distance(base_face, check_face): result = DeepFace.verify(base_face, check_face, enforce_detection=False) return result['distance'] def find_faces(image): outputs = model(image) faces = [] for box in outputs[0].boxes: if float(box.conf) >= FACE_DET_TRESH: x, y, w, h = [int(coord) for coord in box.xywh[0]] x_center, y_center = x + w / 2, y + h / 2 x1 = int(x_center - w) y1 = int(y_center - h) crop_img = image[y1:y1+h, x1:x1+w] faces.append(crop_img) return faces def load_images_from_zip(zip_path): images = [] with zipfile.ZipFile(zip_path, 'r') as zip_file: for file_name in zip_file.namelist(): with zip_file.open(file_name) as file: img_bytes = np.asarray(bytearray(file.read()), dtype=np.uint8) img = cv2.imdecode(img_bytes, cv2.IMREAD_COLOR) images.append(img) return [img for img in images if img is not None] def create_image(images): if not images: return np.zeros((1, 1, 3), dtype=np.uint8) max_width = max([img.shape[1] for img in images]) total_height = sum([img.shape[0] for img in images]) new_image = np.zeros((total_height, max_width, 3), dtype=np.uint8) y_offset = 0 for img in images: new_image[y_offset:y_offset+img.shape[0], :img.shape[1], :] = img y_offset += img.shape[0] new_image = cv2.resize(new_image, (0, 0), fx=0.5, fy=0.5) return new_image def check(avatars_zip, photos_zip): avatars = load_images_from_zip(avatars_zip.name) photos = load_images_from_zip(photos_zip.name) not_found_faces = [] for photo in photos: photo = cv2.cvtColor(photo, cv2.COLOR_RGB2BGR) input_faces = find_faces(photo) for input_face in input_faces: avatars_checked = 0 for avatar in avatars: avatar = cv2.cvtColor(avatar, cv2.COLOR_RGB2BGR) distance = find_distance(avatar, input_face) if distance > FACE_DIST_TRESH: break else: avatars_checked+=1 if avatars_checked == len(avatars): not_found_faces.append(input_face) return create_image(not_found_faces) title = '