Update app.py
Browse files
app.py
CHANGED
@@ -1,6 +1,3 @@
|
|
1 |
-
# Installation commands (run these first in Colab)
|
2 |
-
# !pip install deepface==0.0.79 tensorflow==2.10.0 opencv-python-headless==4.7.0.72 gradio==3.50.2
|
3 |
-
|
4 |
import gradio as gr
|
5 |
import cv2
|
6 |
import numpy as np
|
@@ -12,13 +9,6 @@ import os
|
|
12 |
import shutil
|
13 |
import pandas as pd
|
14 |
|
15 |
-
# Google Drive integration (for Colab)
|
16 |
-
try:
|
17 |
-
from google.colab import drive
|
18 |
-
drive.mount('/content/drive')
|
19 |
-
except:
|
20 |
-
pass
|
21 |
-
|
22 |
def verify_faces(img1, img2, threshold=0.6, model="VGG-Face"):
|
23 |
temp_dir = tempfile.mkdtemp()
|
24 |
try:
|
@@ -61,14 +51,15 @@ def find_faces(query_img, db_input, threshold=0.6, model="VGG-Face"):
|
|
61 |
Image.fromarray(query_img).save(query_path) if isinstance(query_img, np.ndarray) else query_img.save(query_path)
|
62 |
|
63 |
# Handle database input
|
64 |
-
if isinstance(db_input, str):
|
65 |
db_path = db_input
|
66 |
else:
|
67 |
db_path = os.path.join(temp_dir, "db")
|
68 |
os.makedirs(db_path, exist_ok=True)
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
72 |
|
73 |
# Find faces
|
74 |
try:
|
@@ -79,10 +70,12 @@ def find_faces(query_img, db_input, threshold=0.6, model="VGG-Face"):
|
|
79 |
distance_metric="cosine",
|
80 |
silent=True
|
81 |
)
|
82 |
-
except:
|
83 |
-
return None, {"error": "
|
84 |
|
85 |
df = dfs[0] if isinstance(dfs, list) else dfs
|
|
|
|
|
86 |
df = df[df['distance'] <= threshold].sort_values('distance')
|
87 |
|
88 |
# Create visualization
|
@@ -99,10 +92,15 @@ def find_faces(query_img, db_input, threshold=0.6, model="VGG-Face"):
|
|
99 |
for i in range(num_matches):
|
100 |
if i >= len(df): break
|
101 |
match_path = df.iloc[i]['identity']
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
return fig, df[['identity', 'distance']].to_dict('records')
|
108 |
|
@@ -174,8 +172,8 @@ with gr.Blocks(title="Face Recognition Toolkit", theme=gr.themes.Soft()) as demo
|
|
174 |
|
175 |
with gr.Tab("Find Faces"):
|
176 |
query_img = gr.Image(label="Query Image", type="pil")
|
177 |
-
db_input = gr.Textbox("
|
178 |
-
db_files = gr.File(file_count="multiple", label="
|
179 |
find_threshold = gr.Slider(0.1, 1.0, 0.6, label="Similarity Threshold")
|
180 |
find_model = gr.Dropdown(["VGG-Face", "Facenet", "OpenFace"], value="VGG-Face")
|
181 |
find_btn = gr.Button("Find Matches")
|
@@ -184,10 +182,9 @@ with gr.Blocks(title="Face Recognition Toolkit", theme=gr.themes.Soft()) as demo
|
|
184 |
|
185 |
find_btn.click(
|
186 |
find_faces,
|
187 |
-
[query_img,
|
188 |
[find_output, find_json]
|
189 |
)
|
190 |
-
db_files.change(lambda x: None, db_files, db_input)
|
191 |
|
192 |
with gr.Tab("Analyze Face"):
|
193 |
analyze_img = gr.Image(label="Input Image", type="pil")
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
import cv2
|
3 |
import numpy as np
|
|
|
9 |
import shutil
|
10 |
import pandas as pd
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
def verify_faces(img1, img2, threshold=0.6, model="VGG-Face"):
|
13 |
temp_dir = tempfile.mkdtemp()
|
14 |
try:
|
|
|
51 |
Image.fromarray(query_img).save(query_path) if isinstance(query_img, np.ndarray) else query_img.save(query_path)
|
52 |
|
53 |
# Handle database input
|
54 |
+
if isinstance(db_input, str) and os.path.isdir(db_input):
|
55 |
db_path = db_input
|
56 |
else:
|
57 |
db_path = os.path.join(temp_dir, "db")
|
58 |
os.makedirs(db_path, exist_ok=True)
|
59 |
+
if db_input:
|
60 |
+
for i, file in enumerate(db_input):
|
61 |
+
ext = os.path.splitext(file.name)[1]
|
62 |
+
shutil.copy(file.name, os.path.join(db_path, f"img_{i}{ext}"))
|
63 |
|
64 |
# Find faces
|
65 |
try:
|
|
|
70 |
distance_metric="cosine",
|
71 |
silent=True
|
72 |
)
|
73 |
+
except Exception as e:
|
74 |
+
return None, {"error": f"Face detection failed: {str(e)}"}
|
75 |
|
76 |
df = dfs[0] if isinstance(dfs, list) else dfs
|
77 |
+
if df.empty:
|
78 |
+
return None, {"error": "No matches found"}
|
79 |
df = df[df['distance'] <= threshold].sort_values('distance')
|
80 |
|
81 |
# Create visualization
|
|
|
92 |
for i in range(num_matches):
|
93 |
if i >= len(df): break
|
94 |
match_path = df.iloc[i]['identity']
|
95 |
+
if not os.path.exists(match_path):
|
96 |
+
continue
|
97 |
+
try:
|
98 |
+
match_img = cv2.cvtColor(cv2.imread(match_path), cv2.COLOR_BGR2RGB)
|
99 |
+
axes[i+1].imshow(match_img)
|
100 |
+
axes[i+1].set_title(f"Match {i+1}\n{df.iloc[i]['distance']:.4f}")
|
101 |
+
axes[i+1].axis('off')
|
102 |
+
except:
|
103 |
+
continue
|
104 |
|
105 |
return fig, df[['identity', 'distance']].to_dict('records')
|
106 |
|
|
|
172 |
|
173 |
with gr.Tab("Find Faces"):
|
174 |
query_img = gr.Image(label="Query Image", type="pil")
|
175 |
+
db_input = gr.Textbox("", label="Database Path (optional)")
|
176 |
+
db_files = gr.File(file_count="multiple", label="Upload Database Images")
|
177 |
find_threshold = gr.Slider(0.1, 1.0, 0.6, label="Similarity Threshold")
|
178 |
find_model = gr.Dropdown(["VGG-Face", "Facenet", "OpenFace"], value="VGG-Face")
|
179 |
find_btn = gr.Button("Find Matches")
|
|
|
182 |
|
183 |
find_btn.click(
|
184 |
find_faces,
|
185 |
+
[query_img, db_files, find_threshold, find_model],
|
186 |
[find_output, find_json]
|
187 |
)
|
|
|
188 |
|
189 |
with gr.Tab("Analyze Face"):
|
190 |
analyze_img = gr.Image(label="Input Image", type="pil")
|