Internship-day05

这个项目源码发布在github上:

face-match

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
import os
import pandas as pd
import face_recognition


def find_person_info(image_path):
# 看能不能找到给定路径的文件
if not os.path.exists(image_path):
return [], "No such img."
# 给定存放图片的文件夹
folder_path = "db"

# 加载给定路径的文件并生成特征编码,如果图片没有人脸则报错
unknown_image = face_recognition.load_image_file(image_path)
unknown_face_encodings = face_recognition.face_encodings(unknown_image)

if not unknown_face_encodings:
return [], "No faces found in the unknown_image."

matched_persons = [] # 设计一个列表,用来存放匹配到人脸的信息

# 循环,找出提供照片中的每个人脸
for unknown_face_encoding in unknown_face_encodings:

# 返回指定目录下的所有文件和目录名的列表
for filename in os.listdir(folder_path):
# 只处理.jpg和.png文件
if filename.endswith(".jpg") or filename.endswith(".png"):
# 加载给定路径的文件并生成特征编码
known_image = face_recognition.load_image_file(os.path.join(folder_path, filename))
known_face_encodings = face_recognition.face_encodings(known_image)

# 假如在known_face_encodings中没找到人脸,那么跳出循环,下一张
if not known_face_encodings:
continue

# 从 known_face_encodings 列表中取出第一个元素并赋值给 known_face_encoding
known_face_encoding = known_face_encodings[0]

# 比较两个面部编码,看是否匹配,调整tolerance参数,取0.45差不多,还要调
results = face_recognition.compare_faces([known_face_encoding], unknown_face_encoding, tolerance=0.5)

# 打印结果
if results[0]:
# 取文件名为人物id
person_id = filename.split('.')[0]

df = pd.read_excel('info.xlsx')

person_info = df[df['id'].astype(str) == person_id]

# 假如找到了信息
if not person_info.empty:
# 将这个人信息append加入到列表中
matched_persons.append(person_info.iloc[0].to_dict())

if matched_persons:
return matched_persons, None
else:
return [], "No match found."

打印 unknown_image:

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
[[[ 32  71 112]
[ 33 72 113]
[ 33 72 113]
...
[ 35 71 106]
[ 35 71 106]
[ 33 69 104]]

[[ 33 72 113]
[ 33 72 113]
[ 34 73 114]
...
[ 35 71 106]
[ 35 71 106]
[ 33 69 104]]

[[ 34 73 114]
[ 34 73 114]
[ 35 74 115]
...
[ 36 72 107]
[ 36 72 107]
[ 34 70 105]]

...

[[ 2 25 71]
[ 2 25 71]
[ 3 26 73]
...
[ 14 21 74]
[ 12 23 74]
[ 12 23 74]]

[[ 0 23 64]
[ 0 24 64]
[ 2 25 68]
...
[ 13 20 73]
[ 10 22 73]
[ 10 18 73]]

[[ 0 22 59]
[ 0 22 59]
[ 0 23 64]
...
[ 13 20 73]
[ 10 22 73]
[ 8 17 72]]]

打印 unknown_face_encodings:这个是用来存放unknown_face_encoding的一个array

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
[array([-0.13223957,  0.16503266,  0.09020811,  0.00672515, -0.09350206,
-0.00940245, -0.03665374, -0.09436678, 0.12680565, 0.01610284,
0.23214346, -0.01058169, -0.17831463, -0.11720017, -0.02244026,
0.12244396, -0.21053834, -0.13550632, 0.00286131, 0.04644092,
0.10494904, 0.07014632, 0.0892531 , 0.04381904, -0.07422439,
-0.42399305, -0.04031111, -0.11812686, 0.02305087, -0.01154761,
0.01216548, 0.0245845 , -0.25394315, -0.10557299, 0.03783333,
0.07827907, -0.01626904, -0.00509987, 0.18849066, -0.0242721 ,
-0.20650545, 0.11054654, 0.02895997, 0.31742305, 0.16261479,
0.0759404 , 0.05481248, -0.08809394, 0.09429981, -0.21823171,
0.09824699, 0.16703583, 0.08863883, -0.01104275, 0.00278107,
-0.14643633, 0.03028786, 0.02878108, -0.17623518, 0.05836982,
0.1670046 , -0.01511078, 0.01745525, -0.01929321, 0.19001804,
0.02725898, -0.07748701, -0.19153407, 0.02892923, -0.10864975,
-0.05668222, 0.09141017, -0.1782237 , -0.1846647 , -0.32670057,
0.0874635 , 0.40891796, 0.07372297, -0.18304899, 0.03089732,
-0.08080248, 0.08455542, 0.10734302, 0.0760516 , -0.0260337 ,
0.018057 , -0.18947719, 0.06145783, 0.18782443, -0.03918557,
-0.10583983, 0.22502539, 0.0415048 , 0.03528464, 0.03694579,
0.05772862, -0.02676605, 0.06341691, -0.20423572, 0.04492543,
0.0347067 , 0.04718253, -0.02277087, 0.10553455, -0.1783113 ,
0.09799166, -0.03231913, 0.00251438, -0.03181266, -0.04052553,
-0.17417844, -0.02148585, 0.10722338, -0.21874264, 0.25460005,
0.16116001, 0.08119219, 0.13333398, 0.12037521, -0.00283147,
0.00364753, -0.00507532, -0.1807882 , -0.06987992, 0.11120825,
0.00986055, 0.10558957, 0.02575663])]

打印 unknown_face_encoding:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[-0.13223957  0.16503266  0.09020811  0.00672515 -0.09350206 -0.00940245
-0.03665374 -0.09436678 0.12680565 0.01610284 0.23214346 -0.01058169
-0.17831463 -0.11720017 -0.02244026 0.12244396 -0.21053834 -0.13550632
0.00286131 0.04644092 0.10494904 0.07014632 0.0892531 0.04381904
-0.07422439 -0.42399305 -0.04031111 -0.11812686 0.02305087 -0.01154761
0.01216548 0.0245845 -0.25394315 -0.10557299 0.03783333 0.07827907
-0.01626904 -0.00509987 0.18849066 -0.0242721 -0.20650545 0.11054654
0.02895997 0.31742305 0.16261479 0.0759404 0.05481248 -0.08809394
0.09429981 -0.21823171 0.09824699 0.16703583 0.08863883 -0.01104275
0.00278107 -0.14643633 0.03028786 0.02878108 -0.17623518 0.05836982
0.1670046 -0.01511078 0.01745525 -0.01929321 0.19001804 0.02725898
-0.07748701 -0.19153407 0.02892923 -0.10864975 -0.05668222 0.09141017
-0.1782237 -0.1846647 -0.32670057 0.0874635 0.40891796 0.07372297
-0.18304899 0.03089732 -0.08080248 0.08455542 0.10734302 0.0760516
-0.0260337 0.018057 -0.18947719 0.06145783 0.18782443 -0.03918557
-0.10583983 0.22502539 0.0415048 0.03528464 0.03694579 0.05772862
-0.02676605 0.06341691 -0.20423572 0.04492543 0.0347067 0.04718253
-0.02277087 0.10553455 -0.1783113 0.09799166 -0.03231913 0.00251438
-0.03181266 -0.04052553 -0.17417844 -0.02148585 0.10722338 -0.21874264
0.25460005 0.16116001 0.08119219 0.13333398 0.12037521 -0.00283147
0.00364753 -0.00507532 -0.1807882 -0.06987992 0.11120825 0.00986055
0.10558957 0.02575663]

将这个方法的各个小功能拖出来,写成更小的函数,便于维护:

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
import os
import pandas as pd
import face_recognition


def check_image_exists(image_path):
if not os.path.exists(image_path):
raise FileNotFoundError("No such img.")
return True


def load_image_and_generate_encodings(image_path):
image = face_recognition.load_image_file(image_path)
face_encodings = face_recognition.face_encodings(image)
if not face_encodings:
raise ValueError("No faces found in the image.")
return face_encodings


def get_known_face_encodings(folder_path):
known_face_encodings = {}
for filename in os.listdir(folder_path):
if filename.endswith(".jpg") or filename.endswith(".png"):
image = face_recognition.load_image_file(os.path.join(folder_path, filename))
face_encodings = face_recognition.face_encodings(image)
if face_encodings:
known_face_encodings[filename] = face_encodings[0]
return known_face_encodings


def compare_faces(unknown_face_encodings, known_face_encodings):
matched_faces = []
for unknown_face_encoding in unknown_face_encodings:
for filename, known_face_encoding in known_face_encodings.items():
results = face_recognition.compare_faces([known_face_encoding], unknown_face_encoding, tolerance=0.5)
if results[0]:
matched_faces.append(filename.split('.')[0])
return matched_faces


def get_person_info(matched_faces):
df = pd.read_excel('info.xlsx')
matched_persons = []
for person_id in matched_faces:
person_info = df[df['id'].astype(str) == person_id]
if not person_info.empty:
matched_persons.append(person_info.iloc[0].to_dict())
return matched_persons


def find_person_info(image_path):
check_image_exists(image_path)
unknown_face_encodings = load_image_and_generate_encodings(image_path)
known_face_encodings = get_known_face_encodings("db")
matched_faces = compare_faces(unknown_face_encodings, known_face_encodings)
matched_persons = get_person_info(matched_faces)
return matched_persons

相应地,更改 app.py 接口

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
from flask import Flask, request, jsonify
from function import find_person_info # 确保你的function.py文件在同一目录下,或者在Python的搜索路径中

app = Flask(__name__)


@app.route('/find_person_info', methods=['POST'])
def find_person_info_api():
image_path = request.json['image_path']
try:
persons_info = find_person_info(image_path)
return jsonify(persons_info), 200
except FileNotFoundError:
return jsonify({"message": "The image does not exist."}), 200
except ValueError as e:
if str(e) == "No faces found in the image.":
return jsonify({"message": "No faces found in the uploaded image."}), 200
elif "No faces found in the image" in str(e):
return jsonify({"message": "No faces found in one of the known images."}), 200
except Exception:
return jsonify({"message": "No match found."}), 200


if __name__ == '__main__':
app.run(debug=True)

from function import * 这行代码的意思是从 function 模块(也就是 function.py 文件)中导入所有的公有函数和变量。

这种导入方式被称为 “星号” 或 “通配符” 导入。它会导入 function 模块中所有没有以下划线 _ 开头的函数和变量。这种导入方式可以方便地导入模块中的所有内容,但是也有一些缺点:

  1. 如果两个模块都定义了一个同名的函数或变量,那么后导入的模块会覆盖先导入的模块中的函数或变量。
  2. 当你查看代码时,可能不清楚一个函数或变量是从哪个模块导入的,这会使代码更难理解和维护。

因此,尽管 from function import * 这种导入方式很方便,但是在编写大型项目时,通常推荐明确地导入需要的函数和变量,例如 from function import find_person_info