Spaces:
Runtime error
Runtime error
Code optimization
Browse files
app.py
CHANGED
|
@@ -7,6 +7,7 @@ import gradio as gr
|
|
| 7 |
from deepface import DeepFace
|
| 8 |
from ultralytics import YOLO
|
| 9 |
import urllib.request
|
|
|
|
| 10 |
|
| 11 |
with open('config.json', 'r') as f:
|
| 12 |
config = json.load(f)
|
|
@@ -22,9 +23,9 @@ if not os.path.exists(yolo_weights_filename):
|
|
| 22 |
|
| 23 |
model = YOLO(yolo_weights_filename)
|
| 24 |
|
| 25 |
-
def find_distance(base_face, check_face):
|
| 26 |
-
|
| 27 |
-
|
| 28 |
|
| 29 |
def find_faces(image):
|
| 30 |
outputs = model(image)
|
|
@@ -39,12 +40,14 @@ def find_faces(image):
|
|
| 39 |
faces.append(crop_img)
|
| 40 |
return faces
|
| 41 |
|
| 42 |
-
def load_images_from_zip(zip_path):
|
| 43 |
images = []
|
|
|
|
|
|
|
| 44 |
with zipfile.ZipFile(zip_path, 'r') as zip_file:
|
| 45 |
for file_name in zip_file.namelist():
|
| 46 |
with zip_file.open(file_name) as file:
|
| 47 |
-
img_bytes = file.read
|
| 48 |
img = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR)
|
| 49 |
if img is not None:
|
| 50 |
images.append(img)
|
|
@@ -96,26 +99,45 @@ def create_image(images):
|
|
| 96 |
|
| 97 |
return table_cropped
|
| 98 |
|
| 99 |
-
def
|
| 100 |
-
|
| 101 |
-
photos = [cv2.cvtColor(img, cv2.COLOR_RGB2BGR) for img in load_images_from_zip(photos_zip.name)]
|
| 102 |
-
|
| 103 |
-
input_avatars_faces = [find_faces(avatar) for avatar in avatars]
|
| 104 |
-
input_avatars_faces = [face for faces in input_avatars_faces for face in faces]
|
| 105 |
-
|
| 106 |
avatars_faces_count = len(input_avatars_faces)
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
not_found_faces = []
|
| 109 |
|
| 110 |
for photo in photos:
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
return create_image(not_found_faces)
|
| 121 |
|
|
@@ -134,4 +156,4 @@ with gr.Blocks(theme='soft', title='SquadDetective') as blocks:
|
|
| 134 |
outputs=gr.outputs.Image(type='numpy', label='Report')
|
| 135 |
process_button.click(fn=check, inputs=inputs, outputs=outputs)
|
| 136 |
|
| 137 |
-
blocks.launch()
|
|
|
|
| 7 |
from deepface import DeepFace
|
| 8 |
from ultralytics import YOLO
|
| 9 |
import urllib.request
|
| 10 |
+
import asyncio
|
| 11 |
|
| 12 |
with open('config.json', 'r') as f:
|
| 13 |
config = json.load(f)
|
|
|
|
| 23 |
|
| 24 |
model = YOLO(yolo_weights_filename)
|
| 25 |
|
| 26 |
+
async def find_distance(base_face, check_face):
|
| 27 |
+
result = await asyncio.to_thread(DeepFace.verify, base_face, check_face, enforce_detection=False)
|
| 28 |
+
return result['distance']
|
| 29 |
|
| 30 |
def find_faces(image):
|
| 31 |
outputs = model(image)
|
|
|
|
| 40 |
faces.append(crop_img)
|
| 41 |
return faces
|
| 42 |
|
| 43 |
+
async def load_images_from_zip(zip_path):
|
| 44 |
images = []
|
| 45 |
+
loop = asyncio.get_running_loop()
|
| 46 |
+
|
| 47 |
with zipfile.ZipFile(zip_path, 'r') as zip_file:
|
| 48 |
for file_name in zip_file.namelist():
|
| 49 |
with zip_file.open(file_name) as file:
|
| 50 |
+
img_bytes = await loop.run_in_executor(None, file.read)
|
| 51 |
img = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR)
|
| 52 |
if img is not None:
|
| 53 |
images.append(img)
|
|
|
|
| 99 |
|
| 100 |
return table_cropped
|
| 101 |
|
| 102 |
+
async def process_photo_async(photo, input_avatars_faces):
|
| 103 |
+
not_found_faces = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
avatars_faces_count = len(input_avatars_faces)
|
| 105 |
+
input_faces = find_faces(photo)
|
| 106 |
+
for input_face in input_faces:
|
| 107 |
+
for i in range(avatars_faces_count):
|
| 108 |
+
distance = await find_distance(input_avatars_faces[i], input_face)
|
| 109 |
+
if distance <= FACE_DIST_TRESH:
|
| 110 |
+
break
|
| 111 |
+
elif i + 1 == avatars_faces_count:
|
| 112 |
+
not_found_faces.append(input_face)
|
| 113 |
+
return not_found_faces
|
| 114 |
+
|
| 115 |
+
async def check_async(photos, input_avatars_faces, progress):
|
| 116 |
+
tasks = []
|
| 117 |
not_found_faces = []
|
| 118 |
|
| 119 |
for photo in photos:
|
| 120 |
+
task = asyncio.create_task(process_photo_async(photo, input_avatars_faces))
|
| 121 |
+
tasks.append(task)
|
| 122 |
+
|
| 123 |
+
for i, task in enumerate(tasks):
|
| 124 |
+
result = await task
|
| 125 |
+
not_found_faces += result
|
| 126 |
+
progress((i+1)/len(tasks))
|
| 127 |
+
|
| 128 |
+
return not_found_faces
|
| 129 |
+
|
| 130 |
+
def check(avatars_zip, photos_zip, progress=gr.Progress()):
|
| 131 |
+
avatars = asyncio.run(load_images_from_zip(avatars_zip.name))
|
| 132 |
+
avatars = [cv2.cvtColor(avatar, cv2.COLOR_RGB2BGR) for avatar in avatars]
|
| 133 |
+
|
| 134 |
+
photos = asyncio.run(load_images_from_zip(photos_zip.name))
|
| 135 |
+
photos = [cv2.cvtColor(photo, cv2.COLOR_RGB2BGR) for photo in photos]
|
| 136 |
+
|
| 137 |
+
input_avatars_faces = [find_faces(avatar) for avatar in avatars]
|
| 138 |
+
input_avatars_faces = [face for faces in input_avatars_faces for face in faces]
|
| 139 |
+
|
| 140 |
+
not_found_faces = asyncio.run(check_async(photos, input_avatars_faces, progress))
|
| 141 |
|
| 142 |
return create_image(not_found_faces)
|
| 143 |
|
|
|
|
| 156 |
outputs=gr.outputs.Image(type='numpy', label='Report')
|
| 157 |
process_button.click(fn=check, inputs=inputs, outputs=outputs)
|
| 158 |
|
| 159 |
+
blocks.queue(concurrency_count=1).launch()
|