Skip to content

Commit 8b9381f

Browse files
committed
人脸识别
0 parents  commit 8b9381f

21 files changed

+399
-0
lines changed

.idea/.gitignore

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/answer18-1.1.iml

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/profiles_settings.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
1.13 KB
Binary file not shown.
1.95 KB
Binary file not shown.
1.51 KB
Binary file not shown.

face_recognition_init.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import face_recognition
2+
3+
4+
# 初始化已知人脸数据
5+
def face_init_know_res(paths):
6+
known_faces = []
7+
known_faces_name = []
8+
for item in paths:
9+
known_face = face_recognition.load_image_file(item['path'])
10+
known_face_encoding = face_recognition.face_encodings(known_face)[0]
11+
known_faces.append(known_face_encoding)
12+
known_faces_name.append(item['name'])
13+
return known_faces, known_faces_name
14+
15+
16+
# 初始化未知人脸数据(帧的方式)
17+
def face_init_unknown_res(rgb_small_frame):
18+
unknow_face_locations = face_recognition.face_locations(rgb_small_frame)
19+
unknow_face_encodings = face_recognition.face_encodings(rgb_small_frame, unknow_face_locations)
20+
return unknow_face_encodings, unknow_face_locations
21+
22+
23+
# 初始化未知人脸数据(文件图片的方式)
24+
def face_init_unknown_res_file(file):
25+
unknow_face_locations = face_recognition.load_image_file(file)
26+
unknow_face_encodings = face_recognition.face_encodings(unknow_face_locations)[0]
27+
return unknow_face_encodings, unknow_face_locations
28+
29+
30+
# 加载识别,返回识别后的人名
31+
def face_use_test(known_faces, unknown_face_encoding, known_faces_name):
32+
results = face_recognition.compare_faces(known_faces, unknown_face_encoding)
33+
index = results.index(True)
34+
face_name = known_faces_name[index]
35+
return face_name

face_recognition_use.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import cv2
2+
import os
3+
import numpy as np
4+
import face_recognition
5+
from scan_data_face import load_face_data_file
6+
from face_recognition_init import face_init_know_res, face_init_unknown_res
7+
8+
PHOTO = "photo/face.jpg"
9+
10+
# 加载面部数据
11+
def load_known_face(PTAH):
12+
# 加载已知人脸
13+
paths = load_face_data_file(PTAH)
14+
# 计算已知人脸
15+
know_face_encodings, konw_face_names = face_init_know_res(paths)
16+
return know_face_encodings, konw_face_names
17+
18+
19+
# 运行OpenCv读取摄像头
20+
def face_run(know_face_encodings, konw_face_names):
21+
global count
22+
process_this_frame = True
23+
video_capture = cv2.VideoCapture(1, cv2.CAP_DSHOW)
24+
25+
while True:
26+
ret, frame = video_capture.read()
27+
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
28+
rgb_small_frame = small_frame[:, :, ::-1]
29+
30+
if process_this_frame:
31+
unknow_face_encodings, unknow_face_locations = face_init_unknown_res(rgb_small_frame)
32+
33+
face_names = []
34+
for face_encoding in unknow_face_encodings:
35+
matches = face_recognition.compare_faces(know_face_encodings, face_encoding)
36+
name = "Unknown"
37+
38+
face_distances = face_recognition.face_distance(know_face_encodings, face_encoding)
39+
best_match_index = np.argmin(face_distances)
40+
if matches[best_match_index]:
41+
name = konw_face_names[best_match_index]
42+
43+
face_names.append(name)
44+
45+
process_this_frame = not process_this_frame
46+
47+
for (top, right, bottom, left), name in zip(unknow_face_locations, face_names):
48+
top *= 4
49+
right *= 4
50+
bottom *= 4
51+
left *= 4
52+
53+
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
54+
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
55+
font = cv2.FONT_HERSHEY_DUPLEX
56+
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
57+
58+
cv2.imshow('Camera', frame)
59+
k = cv2.waitKey(1)
60+
# 点击窗口关闭按钮退出程序
61+
if k == ord('s'):
62+
pic = cv2.resize(frame, (600, 400), interpolation=cv2.INTER_CUBIC)
63+
cv2.imwrite(PHOTO, pic)
64+
break
65+
if k == ord('q'):
66+
if os.path.exists(PHOTO):
67+
os.remove(PHOTO)
68+
break
69+
if cv2.getWindowProperty('Camera', 0) < 0:
70+
if os.path.exists(PHOTO):
71+
os.remove(PHOTO)
72+
break
73+
74+
video_capture.release()
75+
cv2.destroyAllWindows()
76+
77+

gui.py

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import tkinter as tk
2+
import tkinter.messagebox
3+
import requests
4+
import threading
5+
from pygame import mixer
6+
from PIL import ImageTk
7+
from face_recognition_use import *
8+
from face_recognition_init import *
9+
from multiprocessing.pool import ThreadPool
10+
11+
pool = ThreadPool(processes=1)
12+
13+
# 初始化窗口
14+
window = tk.Tk()
15+
# 窗口标题
16+
window.title('人脸识别系统')
17+
# 创建一个主frame,长在主window窗口上
18+
frame = tk.Frame(window)
19+
frame.grid()
20+
# 窗口图标路径
21+
IMGPATH = "toast/recong.gif"
22+
# 人脸图片位置,自动导入时用
23+
AUTOPATH = "img/face_recognition"
24+
# 音乐地址
25+
MUSIC = "music/music.mp3"
26+
27+
# 需要用到的已知人脸数据
28+
know_face_encodings = []
29+
konw_face_names = []
30+
31+
# 播放音乐组件
32+
mixer.init()
33+
34+
35+
# 显示弹窗
36+
def showmodle(content):
37+
tkinter.messagebox.showinfo(title='提示', message=content)
38+
39+
40+
# 自定义扫描人脸数据(为优化程序体验,没有使用此方法)
41+
def scan_path():
42+
text = tk.StringVar()
43+
text.set('请输入已知人脸目录加载数据(图片名为识别人名)')
44+
r = tk.Label(frame, textvariable=text, bg='blue', font=('Arial', 12), width=50, height=2)
45+
r.grid(row=1, column=0)
46+
47+
def load_lfw():
48+
global know_face_encodings
49+
global konw_face_names
50+
if input1.get() == "":
51+
showmodle("目录不能为空")
52+
else:
53+
text.set("加载中……请稍等……")
54+
btn1.grid_forget()
55+
try:
56+
async_result = pool.apply_async(load_known_face, (input1.get(),))
57+
know_face_encodings, konw_face_names = async_result.get()
58+
showmodle("数据加载完成……")
59+
r.grid_forget()
60+
input1.grid_forget()
61+
start_face_recog()
62+
except:
63+
text.set("路径有误,请重新输入……")
64+
btn1.grid(row=3, column=0)
65+
66+
input1 = tk.Entry(frame, show=None, font=('Arial', 14), width=40)
67+
input1.grid(row=2, column=0)
68+
btn1 = tk.Button(frame, text='加载', font=('Arial', 12), width=10, height=1, command=load_lfw)
69+
btn1.grid(row=3, column=0)
70+
71+
72+
# 自动扫面人脸数据
73+
def scan_path_auto():
74+
global know_face_encodings
75+
global konw_face_names
76+
global AUTOPATH
77+
async_result = pool.apply_async(load_known_face, (AUTOPATH,))
78+
know_face_encodings, konw_face_names = async_result.get()
79+
start_face_recog()
80+
81+
82+
# 显示图片在窗口
83+
def show_face_to_windiw():
84+
photo = ImageTk.PhotoImage(file=IMGPATH)
85+
label_show = tk.Label(frame, imag=photo)
86+
label_show.grid(row=0, column=0, columnspan=2)
87+
label_show.image = photo
88+
89+
90+
# 开始人脸识别
91+
def start_face_recog():
92+
def run(know_face_encodings, konw_face_names):
93+
btn.grid_forget()
94+
face_run(know_face_encodings, konw_face_names)
95+
show_photo()
96+
btn.grid(row=2, column=0, columnspan=2)
97+
98+
label = tk.Label(frame, text='点击开始打开摄像头-按“S”获取识别结果', font=('Arial', 12), width=50, height=2)
99+
label.grid(row=1, column=0, columnspan=2)
100+
btn = tk.Button(frame, text='开始', font=('Arial', 12), width=20, height=1,
101+
command=lambda: run(know_face_encodings, konw_face_names))
102+
btn.grid(row=2, column=0, columnspan=2)
103+
104+
105+
# 读取文件列表、动态加载、显示识别结果
106+
def show_photo():
107+
res = load_face_data_file("photo")
108+
if len(res) == 0:
109+
return
110+
for i in res:
111+
texts = tk.StringVar()
112+
try:
113+
unknow_face_encodings, unknow_face_locations = face_init_unknown_res_file("photo/face.jpg")
114+
name = face_use_test(know_face_encodings, unknow_face_encodings, konw_face_names)
115+
texts.set("识别结果:" + name)
116+
except:
117+
texts.set("未检测到人脸")
118+
showmodle("检测完成")
119+
120+
photo = ImageTk.PhotoImage(file=i['path'])
121+
label_show = tk.Label(frame, imag=photo)
122+
label_show.grid(row=0, column=1)
123+
label_show.image = photo
124+
125+
label = tk.Label(frame, textvariable=texts, bg='yellow', font=('Arial', 12), width=30, height=2)
126+
label.grid(row=1, column=1)
127+
128+
129+
# 获取音乐
130+
def get_music():
131+
# 接口跳转获取真实地址
132+
def get_redirect_url(url):
133+
url = url
134+
headers = {
135+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'
136+
}
137+
response = requests.get(url, headers=headers)
138+
return response
139+
140+
res = requests.get("https://api.uomg.com/api/rand.music?sort=热歌榜&format=json")
141+
res = res.json()
142+
res = get_redirect_url(res['data']['url'])
143+
if os.path.exists(MUSIC):
144+
os.remove(MUSIC)
145+
with open(MUSIC, 'wb') as f:
146+
f.write(res.content)
147+
print("播放")
148+
mixer.music.load(MUSIC)
149+
mixer.music.play()
150+
151+
152+
# 音乐播放、停止
153+
def music():
154+
# 停止播放
155+
def stop_music():
156+
btn1.grid(row=6, column=0, columnspan=2)
157+
btn2.grid_forget()
158+
mixer.music.stop()
159+
mixer.music.unload()
160+
161+
# 开始播放
162+
def play_music():
163+
threading.Thread(target=get_music).start()
164+
btn1.grid_forget()
165+
btn2.grid(row=6, column=0, columnspan=2)
166+
167+
r = tk.Label(frame, text="点击随机播放歌曲", font=('Arial', 12), width=50, height=2)
168+
r.grid(row=4, column=0, columnspan=2)
169+
btn1 = tk.Button(frame, text='播放', font=('Arial', 12), width=10, height=1, command=play_music)
170+
btn1.grid(row=6, column=0, columnspan=2)
171+
btn2 = tk.Button(frame, text='停止', font=('Arial', 12), width=10, height=1, command=stop_music)
172+
173+
174+
# 菜单
175+
def menu():
176+
def hello():
177+
newWindow = tk.Toplevel(window)
178+
tk.Label(newWindow, text="作者:貌似", font=('Arial', 15), width=20, height=2).pack()
179+
tk.Label(newWindow, text="版本:1.1", font=('Arial', 15), width=20, height=2).pack()
180+
tk.Button(newWindow, text="确定", font=('Arial', 12), width=5, height=1, command=newWindow.destroy).pack()
181+
182+
menubar = tk.Menu(window)
183+
menubar.add_command(label="关于", command=hello)
184+
menubar.add_command(label="退出", command=window.quit)
185+
window.config(menu=menubar)
186+
187+
188+
# 实时天气
189+
def weather():
190+
text = tk.StringVar(value="")
191+
r = tk.Label(frame, textvariable=text, font=('Arial', 12), width=50, height=2)
192+
r.grid(row=7, column=0, columnspan=2)
193+
194+
res = requests.get("http://pv.sohu.com/cityjson?ie=utf-8")
195+
res = res.text.split(":")[-1].split("\"")[1][-3:]
196+
res = requests.get(
197+
"https://geoapi.heweather.net/v2/city/lookup?key=1f64433544784f98bce18756551005a4&location=" + str(res))
198+
res = res.json()
199+
res = requests.get("https://devapi.heweather.net/v7/weather/now?location=" + res["location"][0][
200+
"id"] + "&key=1f64433544784f98bce18756551005a4")
201+
res = res.json()
202+
text.set("气温:" + res['now']["temp"] + "℃,天气:" + res['now']["text"])
203+
204+
205+
if __name__ == "__main__":
206+
# 这里开启多线程是为了加载后台数据,如:人脸数据,天气数据。没有加载完成就不显示按钮和提示
207+
threading.Thread(target=weather).start()
208+
show_face_to_windiw()
209+
threading.Thread(target=scan_path_auto).start()
210+
music()
211+
menu()
212+
# 主窗口循环显示
213+
window.mainloop()

img/face_recognition/Obama.jpg

16 KB
Loading

img/face_recognition/Pujing.jpg

2.97 KB
Loading

img/face_recognition/Trump.jpg

4.94 KB
Loading

img/face_recognition/WeiPeng.jpg

89.1 KB
Loading

img/face_recognition/XinHui.jpg

116 KB
Loading

music/music.mp3

1.6 MB
Binary file not shown.

photo/face.jpg

4.32 KB
Loading

0 commit comments

Comments
 (0)