-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathface_recognition_test.py
More file actions
330 lines (268 loc) · 12 KB
/
face_recognition_test.py
File metadata and controls
330 lines (268 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# https://github.com/ageitgey/face_recognition
# Compares two photos and predicts whether they are the same person
# face_recognition.compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6) has been adapted
# added a line to print the score
# print (f"Distance : {face_distance(known_face_encodings, face_encoding_to_check)}")
import face_recognition
import cv2
import os
import time
import sqlite3 as sl
import numpy as np
import io
import json
import pandas as pd
def show_face_landmarks(url):
"""Shows the landmarks of a given face
Args:
url (string):URL or file location of the face
"""
image = face_recognition.load_image_file(url)
face_landmarks_list = face_recognition.face_landmarks(image)
img = cv2.imread(url, cv2.IMREAD_COLOR)
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
ih, iw, ic = img.shape
for face_landmarks in face_landmarks_list:
for key in face_landmarks:
todo = face_landmarks[key]
for i, t in enumerate(todo):
a = t[0]
b = t[1]
cv2.circle(img, (a, b), radius=5, color=(225, 0, 100), thickness=1)
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
txt = f"{str(i)}-{key}"
# cv2.putText(img,txt,(a, b), font, 1, (255,255,255), 1, cv2.LINE_AA)
cv2.imshow("image", img)
cv2.waitKey(0)
def get_known_image(known_image):
"""Gets the numpy array of the known face
Args:
known_image (string): Filename of the file with the known face
unknown_image (string): Filename of the file with the unknown face
Returns:
Boolean: Whether the unknown face is the same as the known face
"""
known_image = face_recognition.load_image_file(known_image)
known_encoding = face_recognition.face_encodings(known_image)[0]
return known_encoding
def indentify_faces(known_image, unknown_image):
"""Checks if the known face is in the unknown image
Args:
known_image (string): Filename of the file with the known face
unknown_image (string): Filename of the file with the unknown face
Returns:
Boolean: Whether the unknown face is the same as the known face
"""
known_image = face_recognition.load_image_file(known_image)
unknown_image = face_recognition.load_image_file(unknown_image)
known_encoding = face_recognition.face_encodings(known_image)[0]
if len (face_recognition.face_encodings(unknown_image))>0:
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
results = face_recognition.compare_faces(
[known_encoding], unknown_encoding, tolerance=0.6
)
else:
results = [False] # no faces in the image
return results
def indentify_faces_with_known_encoding(known_encoding, unknown_image):
"""Checks if the known face is in the unknown image
Args:
known_image (string): Filename of the file with the known face
unknown_image (string): Filename of the file with the unknown face
Returns:
Boolean: Whether the unknown face is the same as the known face
"""
unknown_image = face_recognition.load_image_file(unknown_image)
if len (face_recognition.face_encodings(unknown_image))>0:
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
results = face_recognition.compare_faces(
[known_encoding], unknown_encoding, tolerance=0.6
)
else:
results = [False] # no faces in the image
return results
def show_distance(known_image, unknown_image):
#
"""Load a test image and get the distance to the known image.
Args:
known_image (str): filename of the known image
unknown_image (str): filename of the unknown image to test
Returns:
float: distance to test image. 0 is 100% equal, 1 is unequal
"""
image_known = face_recognition.load_image_file(known_image)
image_known_encoding = [face_recognition.face_encodings(image_known)[0]]
# Load a test image and get encondings for it
image_to_test = face_recognition.load_image_file(unknown_image)
image_to_test_encoding = face_recognition.face_encodings(image_to_test)[0]
a = face_recognition.face_distance(image_known_encoding, image_to_test_encoding)
return a[0]
def index_incl_subdir(dir_name):
"""Makes a SQlite-database with indexes of faces in a directory (incl subdirectory)
Args:
dir_name (str): the directory name to index
"""
dir_name_db = r"C:\Users\rcxsm\Pictures\div\mijn autos\b\dls"
file_name_db = "face_encodings.db"
db_name = dir_name_db + os.sep + file_name_db
con = sl.connect(db_name, detect_types=sl.PARSE_DECLTYPES)
#con = sl.connect(db_name,detect_types=sqlite3.PARSE_COLNAMES)
#con = sqlite3.connect(":memory:", )
cur = con.cursor()
cur.execute("DROP TABLE face_encoding_from_images")
try:
with con:
con.execute("""
CREATE TABLE face_encoding_from_images (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
directory TEXT,
filename TEXT,
face_encoding_in_image json
);
""")
except:
print ("Table exists already")
#sl.register_adapter(np.ndarray, adapt_array)
# SQLite has no facility for a 'nested' column; you'd have to store your
# list as text or binary data blob; serialise it on the way in, deserialise
# it again on the way out.
# How you serialise to text or binary data depends on your use-cases.
# JSON (via the json module) could be suitable if your lists and
# dictionaries consist only of text, numbers, booleans and None
# (with the dictionaries only using strings as keys). JSON is
# supported by a wide range of other languages, so you keep your
# data reasonably compatible. Or you could use pickle, which lets
# you serialise to a binary format and can handle just about anything
# Python can throw at it, but it's specific to Python.
# You can then register an adapter to handle converting between
# the serialisation format and Python lists:
sl.register_adapter(list, adapt_list_to_JSON)
sl.register_converter("json", convert_JSON_to_list)
extensionsToCheck = [".jpg", ".JPG", ".jpeg", ".png", ".PNG"]
for subdir, dirs, files in os.walk(dir_name):
f = len(files)
for idx, file in enumerate(files):
print(f"{subdir =}")
print(f"{idx}/{f} - {file =}")
unknown_image = subdir + os.sep + file
unknown_image_x=face_recognition.load_image_file(unknown_image)
if len (face_recognition.face_encodings(unknown_image_x))>0:
face_encoding_in_image = face_recognition.face_encodings(unknown_image_x)[0]
print (face_encoding_in_image)
face_encoding_in_image_as_list = face_encoding_in_image.tolist()
print (face_encoding_in_image_as_list)
else:
print (f"No face found in {file}")
if face_encoding_in_image is not None:
sql = "INSERT INTO face_encoding_from_images (directory, filename, face_encoding_in_image) values (?,?,?)"
data = (subdir, file, face_encoding_in_image_as_list)
with con:
con.execute(sql , data)
print (f"Inserted {file}")
def check_if_image_is_in_database(unknown_image):
"""Checks if an image is in the SQlite database
Args:
unknown_image (str): url of the image to test
Returns:
bool: TRUE when in database
"""
unknown_image = face_recognition.load_image_file(unknown_image)
sl.register_converter("json", convert_JSON_to_list)
dir_name_db = 'C:\\Users\\rcxsm\\Pictures\\div\\'
file_name_db = "face_encodings.db"
db_name = dir_name_db + os.sep + file_name_db
con = sl.connect(db_name, detect_types=sl.PARSE_DECLTYPES)
sql_statement = "SELECT * FROM face_encoding_from_images"
df = pd.read_sql(sql_statement, con)
for i in range(len(df)):
known_encoding = np.array(df.iloc[i,3])
if len (face_recognition.face_encodings(unknown_image))>0:
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
results = face_recognition.compare_faces(
[known_encoding], unknown_encoding, tolerance=0.6
)
if results[0] == True:
print ("FOUND")
print ("ID")
print (df.iloc[i,0])
print ("subdir")
print (df.iloc[i,1])
print ("filename")
print (df.iloc[i,2])
return True
return False
def adapt_list_to_JSON(lst):
return json.dumps(lst).encode('utf8')
def convert_JSON_to_list(data):
return json.loads(data.decode('utf8'))
def read_incl_subdir(known_image, test_dir, target_dir):
"""Reads the file, checks if the person is the same as on the known image
and in that case move the file to the target directory
Args:
known_image (str): The file with the known face
test_dir (str): The directory to check
target_dir (str): The target directory
"""
known_encoding = get_known_image(known_image)
extensionsToCheck = [".jpg", ".JPG", ".jpeg", ".png", ".PNG"]
for subdir, dirs, files in os.walk(test_dir):
f = len(files)
for idx, file in enumerate(files):
for e in extensionsToCheck:
if file.endswith(e):
print(f"{idx+1}/{f} - {subdir}/{file =}")
unknown_image = subdir + os.sep + file
#try:
result = indentify_faces_with_known_encoding(known_encoding, unknown_image)
print (result)
if result[0] == True:
print(f"Moving {file}")
target_file_name = target_dir + os.sep + file
print(target_file_name)
os.replace(unknown_image, target_file_name)
else:
print("Not the same")
# print(f"error with {file}")
def main():
s1 = int(time.time())
# known_image = r"C:\Users\rcxsm\Downloads\Gal_Gadot_by_Gage_Skidmore_4_600.jpg"
# test_dir = r"C:\Users\rcxsm\Pictures\div\galtest"
# target_dir = r"C:\Users\rcxsm\Pictures\div\\galtarget"
# result = indentify_faces(known_image, unknown_image)
# print (result)
known_image = (
r"C:\Users\rcxsm\Downloads\adar2.jpg"
)
unknown_image = r"C:\Users\rcxsm\Downloads\adar3.jpg"
mode = "index_subdirs"
mode = "check_if_in_database"
mode = "show_distance"
if mode == "show_distance":
show_face_landmarks(known_image)
show_face_landmarks(unknown_image)
distance = show_distance(known_image, unknown_image)
result = indentify_faces(known_image, unknown_image)
print(f"Distance: {distance} - {result}")
elif mode == "look_for_my_friend":
# known_image = r"C:\Users\rcxsm\Pictures\div\known.jpg"
# target_dir = r"C:\Users\rcxsm\Pictures\div\target_dir\"
test_dir_ = [r"C:\Users\rcxsm\Pictures\div\test_dir"]
for test_dir in test_dir_:
read_incl_subdir(known_image, test_dir, target_dir)
elif mode == "index_subdirs":
test_dir_ = [r"C:\Users\rcxsm\Pictures\div\test_dir",]
for test_dir in test_dir_:
index_incl_subdir(test_dir)
elif mode == "check_if_in_database":
image_to_check = r"C:\Users\rcxsm\Pictures\div\check_whether_in_database.jpg"
result = check_if_image_is_in_database(image_to_check)
if result == True:
print ("I move it")
else:
print ("I dont move it")
else:
print("ERROR in /mode/")
s2 = int(time.time())
s2x = s2 - s1
print("Processing took " + str(s2x) + " seconds ....")
main()