Spaces:
Running
Running
Add Database Functionality
Browse files- app.py +160 -56
- helpers.py +15 -1
app.py
CHANGED
@@ -4,31 +4,64 @@ import gradio as gr
|
|
4 |
from helpers import *
|
5 |
import shutil
|
6 |
from PIL import Image
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
detector = load_detector()
|
9 |
model = load_model()
|
10 |
|
11 |
-
source_imgs = []
|
12 |
-
for r, _, f in os.walk(os.getcwd() + "/images"):
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
source_faces = []
|
23 |
-
for img in source_imgs:
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
source_embeddings = get_embeddings(model, source_faces)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
def find_names(image, minSize, minConf):
|
34 |
imgs, _ = extract_faces(detector, image)
|
@@ -37,12 +70,11 @@ def find_names(image, minSize, minConf):
|
|
37 |
if((face.size[0] * face.size[1]) > minSize):
|
38 |
ims.append(face)
|
39 |
imgs = ims
|
40 |
-
|
41 |
embeds = get_embeddings(model, imgs)
|
42 |
d = np.zeros((len(source_embeddings), len(embeds)))
|
43 |
for i, s in enumerate(source_embeddings):
|
44 |
for j, t in enumerate(embeds):
|
45 |
-
d[i][j] = findCosineDistance(s, t)
|
46 |
ids = np.argmin(d, axis = 0)
|
47 |
names = []
|
48 |
for j, i in enumerate(ids):
|
@@ -53,10 +85,12 @@ def find_names(image, minSize, minConf):
|
|
53 |
recognition(imgs, ids, names, source_faces, d, source_imgs)
|
54 |
return ",".join(names), "Recognition.jpg"
|
55 |
|
|
|
|
|
56 |
detect = gr.Interface(
|
57 |
find_names,
|
58 |
[gr.Image(type="filepath", label="Class Photo"), gr.Number(label = "Minimum Size"), gr.Number(label = "Minimum Confidence")],
|
59 |
-
["
|
60 |
examples = [
|
61 |
[os.path.join(os.path.dirname(__file__), "examples/group1.jpg"), 1000, 0.3],
|
62 |
[os.path.join(os.path.dirname(__file__), "examples/group2.jpg"), 1000, 0.3]
|
@@ -65,20 +99,16 @@ detect = gr.Interface(
|
|
65 |
|
66 |
|
67 |
def upload_files(files):
|
|
|
68 |
if not os.path.exists(os.path.join(os.getcwd(), "temp")):
|
69 |
os.mkdir(os.path.join(os.getcwd(), "temp"))
|
70 |
for file in files:
|
|
|
|
|
71 |
shutil.move(file.name, os.path.join(os.getcwd(), "temp", file.name.split('\\')[-1]))
|
|
|
72 |
return None, "Uploaded!"
|
73 |
|
74 |
-
with gr.Blocks() as upload:
|
75 |
-
gr.Markdown("# Select Images to Upload and click Upload")
|
76 |
-
with gr.Row():
|
77 |
-
input = gr.Files(file_types=[".jpg", ".jpeg", ".png"], label="Upload images")
|
78 |
-
# input = gr.Image(type="filepath")
|
79 |
-
output = gr.Textbox()
|
80 |
-
upload_btn = gr.Button(value="Upload")
|
81 |
-
upload_btn.click(upload_files, inputs=[input], outputs=[input, output])
|
82 |
|
83 |
def load_image():
|
84 |
global i, imgs
|
@@ -87,45 +117,119 @@ def load_image():
|
|
87 |
for image in images:
|
88 |
faces, id = extract_faces(detector, os.path.join(os.getcwd(), "temp", image))
|
89 |
# imgs.append(Image.open(os.path.join(os.getcwd(), "temp", image)))
|
90 |
-
imgs.append(faces
|
91 |
-
return imgs[0], "Loaded!"
|
92 |
-
|
93 |
-
def save_img(label):
|
94 |
-
global i, imgs
|
95 |
-
imgs[i].save(os.path.join(os.getcwd(), "images", f"{label}.jpg"))
|
96 |
i+=1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
if i < len(imgs):
|
98 |
-
|
|
|
|
|
99 |
else:
|
100 |
clear()
|
101 |
-
return None, "Finished!"
|
102 |
|
103 |
def clear():
|
104 |
global i, imgs
|
105 |
i = 0
|
106 |
imgs = None
|
107 |
-
shutil.rmtree(os.path.join(os.getcwd(), "temp"))
|
108 |
-
return None, None
|
109 |
|
110 |
-
i =
|
111 |
imgs = None
|
112 |
|
113 |
-
with gr.Blocks() as
|
|
|
114 |
with gr.Row():
|
115 |
-
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
with gr.Row():
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
tabbed_interface = gr.TabbedInterface(
|
126 |
-
[detect, upload,
|
127 |
-
["Attendance", "
|
128 |
)
|
129 |
if __name__ == "__main__":
|
130 |
-
tabbed_interface.launch()
|
131 |
-
|
|
|
4 |
from helpers import *
|
5 |
import shutil
|
6 |
from PIL import Image
|
7 |
+
import sqlite3
|
8 |
+
import pathlib
|
9 |
+
|
10 |
+
conn = sqlite3.connect('database.db', check_same_thread=False)
|
11 |
+
c = conn.cursor()
|
12 |
+
create(c)
|
13 |
|
14 |
detector = load_detector()
|
15 |
model = load_model()
|
16 |
|
17 |
+
# source_imgs = []
|
18 |
+
# for r, _, f in os.walk(os.getcwd() + "/images"):
|
19 |
+
# for file in f:
|
20 |
+
# if (
|
21 |
+
# (".jpg" in file.lower())
|
22 |
+
# or (".jpeg" in file.lower())
|
23 |
+
# or (".png" in file.lower())
|
24 |
+
# ):
|
25 |
+
# exact_path = r + "/" + file
|
26 |
+
# source_imgs.append(exact_path)
|
27 |
+
|
28 |
+
# source_faces = []
|
29 |
+
# for img in source_imgs:
|
30 |
+
# try:
|
31 |
+
# faces, id = extract_faces(detector, img)
|
32 |
+
# source_faces.append(faces[id])
|
33 |
+
# # source_faces.append(Image.open(img))
|
34 |
+
# except Exception as e:
|
35 |
+
# print(f"Skipping {img}, {e}")
|
36 |
+
|
37 |
+
# source_embeddings = get_embeddings(model, source_faces)
|
38 |
+
|
39 |
+
def init():
|
40 |
+
source_imgs = c.execute("SELECT image FROM students").fetchall()
|
41 |
+
cwd = os.getcwd()
|
42 |
+
source_imgs = [os.path.join(cwd, "images", s[0]) for s in source_imgs]
|
43 |
+
source_faces = [Image.open(s) for s in source_imgs]
|
44 |
+
# source_embeddings = get_embeddings(model, source_faces)
|
45 |
+
source_embeddings = c.execute("SELECT embeddings FROM students").fetchall()
|
46 |
+
source_embeddings = [os.path.join(cwd, "embeds", s[0]) for s in source_embeddings]
|
47 |
+
source_embeddings = [np.load(s) for s in source_embeddings]
|
48 |
+
names = c.execute("SELECT name FROM students").fetchall()
|
49 |
+
names = [n[0] for n in names]
|
50 |
+
return names, source_faces, source_embeddings
|
51 |
+
|
52 |
+
|
53 |
+
def init():
|
54 |
+
source_imgs = c.execute("SELECT image FROM students").fetchall()
|
55 |
+
cwd = os.getcwd()
|
56 |
+
source_imgs = [os.path.join(cwd, "images", s[0]) for s in source_imgs]
|
57 |
+
source_faces = [Image.open(s) for s in source_imgs]
|
58 |
+
# source_embeddings = get_embeddings(model, source_faces)
|
59 |
+
source_embeddings = c.execute("SELECT embeddings FROM students").fetchall()
|
60 |
+
source_embeddings = [os.path.join(cwd, "embeds", s[0]) for s in source_embeddings]
|
61 |
+
source_embeddings = [np.load(s) for s in source_embeddings]
|
62 |
+
names = c.execute("SELECT name FROM students").fetchall()
|
63 |
+
names = [n[0] for n in names]
|
64 |
+
return names, source_faces, source_embeddings
|
65 |
|
66 |
def find_names(image, minSize, minConf):
|
67 |
imgs, _ = extract_faces(detector, image)
|
|
|
70 |
if((face.size[0] * face.size[1]) > minSize):
|
71 |
ims.append(face)
|
72 |
imgs = ims
|
|
|
73 |
embeds = get_embeddings(model, imgs)
|
74 |
d = np.zeros((len(source_embeddings), len(embeds)))
|
75 |
for i, s in enumerate(source_embeddings):
|
76 |
for j, t in enumerate(embeds):
|
77 |
+
d[i][j] = findCosineDistance(s.squeeze(), t)
|
78 |
ids = np.argmin(d, axis = 0)
|
79 |
names = []
|
80 |
for j, i in enumerate(ids):
|
|
|
85 |
recognition(imgs, ids, names, source_faces, d, source_imgs)
|
86 |
return ",".join(names), "Recognition.jpg"
|
87 |
|
88 |
+
source_imgs, source_faces, source_embeddings = init()
|
89 |
+
|
90 |
detect = gr.Interface(
|
91 |
find_names,
|
92 |
[gr.Image(type="filepath", label="Class Photo"), gr.Number(label = "Minimum Size"), gr.Number(label = "Minimum Confidence")],
|
93 |
+
[gr.Textbox(label = "Roll No") ,gr.Image(type = "filepath", label="Matching")],
|
94 |
examples = [
|
95 |
[os.path.join(os.path.dirname(__file__), "examples/group1.jpg"), 1000, 0.3],
|
96 |
[os.path.join(os.path.dirname(__file__), "examples/group2.jpg"), 1000, 0.3]
|
|
|
99 |
|
100 |
|
101 |
def upload_files(files):
|
102 |
+
global i, imgs
|
103 |
if not os.path.exists(os.path.join(os.getcwd(), "temp")):
|
104 |
os.mkdir(os.path.join(os.getcwd(), "temp"))
|
105 |
for file in files:
|
106 |
+
# faces, id = extract_faces(detector, os.path.join(os.getcwd(), "temp", file))
|
107 |
+
# imgs.append(faces)
|
108 |
shutil.move(file.name, os.path.join(os.getcwd(), "temp", file.name.split('\\')[-1]))
|
109 |
+
|
110 |
return None, "Uploaded!"
|
111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
def load_image():
|
114 |
global i, imgs
|
|
|
117 |
for image in images:
|
118 |
faces, id = extract_faces(detector, os.path.join(os.getcwd(), "temp", image))
|
119 |
# imgs.append(Image.open(os.path.join(os.getcwd(), "temp", image)))
|
120 |
+
imgs.append(faces)
|
|
|
|
|
|
|
|
|
|
|
121 |
i+=1
|
122 |
+
shutil.rmtree(os.path.join(os.getcwd(), "temp"))
|
123 |
+
return imgs[i], "Loaded!", None, None
|
124 |
+
|
125 |
+
def save_img(label, email, roll, selected):
|
126 |
+
global i, imgs, source_imgs, source_faces, source_embeddings
|
127 |
+
if label:
|
128 |
+
imgs[i][int(selected)].save(os.path.join(os.getcwd(), "images", f"{roll}.jpg"))
|
129 |
+
np.save(os.path.join(os.getcwd(), "embeds", f"{roll}.npy"),get_embeddings(model, [imgs[i][int(selected)]]))
|
130 |
+
insert(c, label, email, roll, f"{roll}.jpg", f"{roll}.npy")
|
131 |
+
conn.commit()
|
132 |
+
source_imgs, source_faces, source_embeddings = init()
|
133 |
+
|
134 |
+
imgs[i].pop(int(selected))
|
135 |
+
if(len(imgs[i]) == 0):
|
136 |
+
i+=1
|
137 |
if i < len(imgs):
|
138 |
+
if not label:
|
139 |
+
return imgs[i], None, None, None
|
140 |
+
return imgs[i], "Saved!", None, None
|
141 |
else:
|
142 |
clear()
|
143 |
+
return None, "Finished!", None, None
|
144 |
|
145 |
def clear():
|
146 |
global i, imgs
|
147 |
i = 0
|
148 |
imgs = None
|
149 |
+
# shutil.rmtree(os.path.join(os.getcwd(), "temp"))
|
150 |
+
return None, None, None, None
|
151 |
|
152 |
+
i = -1
|
153 |
imgs = None
|
154 |
|
155 |
+
with gr.Blocks() as upload:
|
156 |
+
gr.Markdown("# Select Images to Upload and click Upload")
|
157 |
with gr.Row():
|
158 |
+
files = gr.Files(file_types=[".jpg", ".jpeg", ".png"], label="Upload images")
|
159 |
+
# input = gr.Image(type="filepath")
|
160 |
+
alert = gr.Textbox()
|
161 |
+
upload_btn = gr.Button(value="Upload")
|
162 |
+
upload_btn.click(upload_files, inputs=[files], outputs=[files, alert])
|
163 |
+
with gr.Accordion("Annotate", open=False):
|
164 |
+
with gr.Row():
|
165 |
+
with gr.Column():
|
166 |
+
input = gr.Textbox(label = "Name")
|
167 |
+
email = gr.Textbox(label = "Email")
|
168 |
+
roll = gr.Textbox(label = "Roll No")
|
169 |
+
selected = gr.Number(visible=False)
|
170 |
+
def get_select_index(evt: gr.SelectData):
|
171 |
+
return evt.index
|
172 |
+
output = gr.Gallery(label="Found Faces", height = 400)
|
173 |
+
output.select(get_select_index, None, selected)
|
174 |
+
with gr.Row():
|
175 |
+
next_btn = gr.Button(value="Next")
|
176 |
+
next_btn.click(load_image, inputs=[], outputs=[output, input, email, roll])
|
177 |
+
save_btn = gr.Button(value="Save")
|
178 |
+
save_btn.click(save_img, inputs=[input, email, roll, selected], outputs=[output, input, email, roll])
|
179 |
+
clear_btn = gr.Button(value="Clear")
|
180 |
+
clear_btn.click(clear, inputs=[], outputs=[output, input, email, roll])
|
181 |
+
# with gr.Blocks() as annotate:
|
182 |
+
|
183 |
+
def match(name, roll):
|
184 |
+
if roll:
|
185 |
+
results = c.execute(f"SELECT name, roll_no, image from students WHERE roll_no = {roll}").fetchall()
|
186 |
+
elif name:
|
187 |
+
results = c.execute(f'SELECT name, roll_no, image from students WHERE name = "{name}"').fetchall()
|
188 |
+
else:
|
189 |
+
results = c.execute(f"SELECT name, roll_no, image from students").fetchall()
|
190 |
+
names = []
|
191 |
+
rolls = []
|
192 |
+
images = []
|
193 |
+
cwd = os.getcwd()
|
194 |
+
for r in results:
|
195 |
+
names.append(r[0])
|
196 |
+
rolls.append(r[1])
|
197 |
+
images.append(os.path.join(cwd, "images", r[2]))
|
198 |
+
return names, rolls, images, images
|
199 |
+
|
200 |
+
def update(name, roll, rolls, img, selected):
|
201 |
+
global source_imgs, source_faces, source_embeddings
|
202 |
+
c.execute(f'UPDATE students SET name = "{name}", roll_no = {roll} where roll_no = {rolls[int(selected)]}')
|
203 |
+
conn.commit()
|
204 |
+
source_imgs, source_faces, source_embeddings = init()
|
205 |
+
result = c.execute("SELECT name, roll_no from students").fetchall()
|
206 |
+
names = [r[0] for r in result]
|
207 |
+
rolls = [r[1] for r in result]
|
208 |
+
return None, None, img, img, names, rolls
|
209 |
+
|
210 |
+
with gr.Blocks() as find:
|
211 |
with gr.Row():
|
212 |
+
with gr.Column():
|
213 |
+
name = gr.Textbox(label = "Name")
|
214 |
+
roll = gr.Textbox(label = "Roll No")
|
215 |
+
image = gr.Gallery(label = "Matches", height = 400)
|
216 |
+
with gr.Row():
|
217 |
+
names = gr.State()
|
218 |
+
rolls = gr.State()
|
219 |
+
images = gr.State()
|
220 |
+
selected = gr.Number(visible=False)
|
221 |
+
find_btn = gr.Button(value = "Find")
|
222 |
+
find_btn.click(match, inputs = [name, roll], outputs = [names, rolls, image, images])
|
223 |
+
update_btn = gr.Button(value = "Update")
|
224 |
+
update_btn.click(update, inputs = [name, roll, rolls, images, selected], outputs = [name, roll, image, images, names, rolls])
|
225 |
+
clear_btn = gr.ClearButton([name, roll, image])
|
226 |
+
def get_select_index(evt: gr.SelectData, names, rolls):
|
227 |
+
return names[evt.index], rolls[evt.index], evt.index
|
228 |
+
image.select(get_select_index, [names, rolls], [name, roll, selected])
|
229 |
|
230 |
tabbed_interface = gr.TabbedInterface(
|
231 |
+
[detect, upload, find],
|
232 |
+
["Attendance", "Register", "Find"],
|
233 |
)
|
234 |
if __name__ == "__main__":
|
235 |
+
tabbed_interface.launch()
|
|
helpers.py
CHANGED
@@ -3,6 +3,8 @@ from PIL import Image
|
|
3 |
import numpy as np
|
4 |
from swin import load_model, get_embeddings
|
5 |
import matplotlib.pyplot as plt
|
|
|
|
|
6 |
|
7 |
def load_detector():
|
8 |
# load model
|
@@ -52,4 +54,16 @@ def recognition(imgs, ids, names, source_faces, d, source_imgs):
|
|
52 |
axes[i, j].set_title(f"Roll No.:{source_imgs[ids[img_count]].split('/')[-1].split('.')[0]}")
|
53 |
axes[i, j].imshow(source_faces[ids[img_count]])
|
54 |
axes[i, j].set_axis_off()
|
55 |
-
plt.savefig("Recognition.jpg")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
import numpy as np
|
4 |
from swin import load_model, get_embeddings
|
5 |
import matplotlib.pyplot as plt
|
6 |
+
import sqlite3
|
7 |
+
import pathlib
|
8 |
|
9 |
def load_detector():
|
10 |
# load model
|
|
|
54 |
axes[i, j].set_title(f"Roll No.:{source_imgs[ids[img_count]].split('/')[-1].split('.')[0]}")
|
55 |
axes[i, j].imshow(source_faces[ids[img_count]])
|
56 |
axes[i, j].set_axis_off()
|
57 |
+
plt.savefig("Recognition.jpg")
|
58 |
+
|
59 |
+
def create(c):
|
60 |
+
pathlib.Path("images").mkdir(parents=True, exist_ok=True)
|
61 |
+
pathlib.Path("embeds").mkdir(parents=True, exist_ok=True)
|
62 |
+
c.execute('''CREATE TABLE IF NOT EXISTS students
|
63 |
+
(name text, email text, roll_no text, image text, embeddings text)''')
|
64 |
+
|
65 |
+
c.execute('''CREATE TABLE IF NOT EXISTS attendance
|
66 |
+
(date text, roll_no text, present text)''')
|
67 |
+
|
68 |
+
def insert(c, name, email, roll_no, image, embeddings):
|
69 |
+
c.execute("INSERT INTO students VALUES (?, ?, ?, ?, ?)", (name, email, roll_no, image, embeddings))
|