Internship-day06
To improve the efficiency of the program, by saving face-encodings in a new file: ‘face_encodings.pkl’, instead of getting all the know_face_encodings each time when posts a request.
Before: 0.15s
Now: 1.1920928955078125e-05To improve the efficiency again, create a Thread Pool in function.
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
40def compare_faces(unknown_face_encodings, known_face_encodings):
# 创建一个空列表来存储匹配的面部
matched_faces = []
# 定义一个内部函数,它接受一个未知的面部编码作为参数
def compare_face(unknown_face_encoding):
# 对于每个已知的面部编码
# known_face_encodings.items()方法返回一个包含字典所有项的列表,每个项是一个元组,元组的第一个元素是键,第二个元素是值。
for filename, known_face_encoding in known_face_encodings.items():
# 使用face_recognition.compare_faces函数来比较未知的面部编码和已知的面部编码
results = face_recognition.compare_faces([known_face_encoding], unknown_face_encoding, tolerance)
# 如果找到匹配的面部,返回匹配的面部的文件名(不包括扩展名)
if results[0]:
return filename.split('.')[0]
# 如果没有找到匹配的面部,返回None
return None
# 创建一个ThreadPoolExecutor实例,这是一个线程池。max_workers=4参数表示线程池中最多可以有4个线程同时运行
with ThreadPoolExecutor(max_workers=4) as executor:
# 使用executor.submit方法为每个未知的面部编码提交一个任务到线程池
# 每个任务就是调用compare_face函数并传入一个未知的面部编码
# executor.submit方法返回一个Future对象,这个对象代表一个尚未完成的计算
# Future对象代表一个尚未完成的计算。当提交一个任务到ThreadPoolExecutor(或者其他类型的Executor),它会立即返回一个Future对象
futures = {executor.submit(compare_face, face_encoding): face_encoding for face_encoding in unknown_face_encodings}
# 使用as_completed函数来迭代已完成的Future对象
for future in as_completed(futures):
# 对于每个已完成的Future对象,获取它的结果(即compare_face函数的返回值)
face = futures[future]
try:
result = future.result()
# 如果结果不是None,就将结果添加到matched_faces列表中
if result is not None:
matched_faces.append(result)
# 如果在获取结果时发生异常,打印一个错误消息
except Exception as exc:
print('%r generated an exception: %s' % (face, exc))
# 返回matched_faces列表,这个列表包含了所有匹配的面部的文件名
return matched_facesNew a js file and a html file, allowing coders to submit images in browsers.