diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 7e1f3a4..2bfc0ba 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,6 +5,8 @@
+
+
@@ -16,7 +18,7 @@
-
+
@@ -28,6 +30,7 @@
@@ -57,26 +60,28 @@
- {
- "keyToString": {
- "ASKED_ADD_EXTERNAL_FILES": "true",
- "Python.add_face.executor": "Run",
- "Python.match_face.executor": "Run",
- "Python.scanf_face.executor": "Run",
- "Python.sqlite.executor": "Run",
- "RunOnceActivity.OpenProjectViewOnStart": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "SHARE_PROJECT_CONFIGURATION_FILES": "true",
- "git-widget-placeholder": "master",
- "node.js.detected.package.eslint": "true",
- "node.js.detected.package.tslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "node.js.selected.package.tslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
- "vue.rearranger.settings.migration": "true"
+
+}]]>
@@ -101,6 +106,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173,6 +201,7 @@
+
@@ -206,6 +235,11 @@
+
+
+
+
+
@@ -262,7 +296,8 @@
-
+
+
\ No newline at end of file
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..1379bb9
--- /dev/null
+++ b/app.py
@@ -0,0 +1,26 @@
+from flask import Flask, render_template
+import sqlite3
+import subprocess
+
+#subprocess.Popen(["python", "scanf_face.py"])
+
+
+app = Flask(__name__)
+
+# 从数据库中获取匹配日志记录
+def get_match_logs(db_name="face_database.db"):
+ conn = sqlite3.connect(db_name)
+ c = conn.cursor()
+ c.execute("SELECT name, identity, image_path, match_time FROM match_logs")
+ logs = c.fetchall()
+ conn.close()
+ return logs
+
+# 首页,展示匹配记录
+@app.route('/')
+def index():
+ logs = get_match_logs()
+ return render_template('index.html', logs=logs)
+
+if __name__ == '__main__':
+ app.run(debug=True)
diff --git a/captured_faces/face_1.jpg b/captured_faces/face_1.jpg
index 27719a5..0db9b57 100644
Binary files a/captured_faces/face_1.jpg and b/captured_faces/face_1.jpg differ
diff --git a/captured_faces/face_10.jpg b/captured_faces/face_10.jpg
index 291e3b8..b6dff5f 100644
Binary files a/captured_faces/face_10.jpg and b/captured_faces/face_10.jpg differ
diff --git a/captured_faces/face_2.jpg b/captured_faces/face_2.jpg
index b82cb0f..e147e0a 100644
Binary files a/captured_faces/face_2.jpg and b/captured_faces/face_2.jpg differ
diff --git a/captured_faces/face_3.jpg b/captured_faces/face_3.jpg
index 349a766..b8ba8dd 100644
Binary files a/captured_faces/face_3.jpg and b/captured_faces/face_3.jpg differ
diff --git a/captured_faces/face_4.jpg b/captured_faces/face_4.jpg
index efbdcd2..bd15c4c 100644
Binary files a/captured_faces/face_4.jpg and b/captured_faces/face_4.jpg differ
diff --git a/captured_faces/face_5.jpg b/captured_faces/face_5.jpg
index 74b8afe..42d215b 100644
Binary files a/captured_faces/face_5.jpg and b/captured_faces/face_5.jpg differ
diff --git a/captured_faces/face_6.jpg b/captured_faces/face_6.jpg
index 55eef8e..d586a5e 100644
Binary files a/captured_faces/face_6.jpg and b/captured_faces/face_6.jpg differ
diff --git a/captured_faces/face_7.jpg b/captured_faces/face_7.jpg
index 7c2613f..ce2b7af 100644
Binary files a/captured_faces/face_7.jpg and b/captured_faces/face_7.jpg differ
diff --git a/captured_faces/face_8.jpg b/captured_faces/face_8.jpg
index 8692d37..6163799 100644
Binary files a/captured_faces/face_8.jpg and b/captured_faces/face_8.jpg differ
diff --git a/captured_faces/face_9.jpg b/captured_faces/face_9.jpg
index b49a56d..248b71c 100644
Binary files a/captured_faces/face_9.jpg and b/captured_faces/face_9.jpg differ
diff --git a/face_database.db b/face_database.db
deleted file mode 100644
index 64a6f7d..0000000
Binary files a/face_database.db and /dev/null differ
diff --git a/match_log.txt b/match_log.txt
new file mode 100644
index 0000000..e69de29
diff --git a/scanf_face.py b/scanf_face.py
index 2d60509..8303e95 100644
--- a/scanf_face.py
+++ b/scanf_face.py
@@ -3,55 +3,17 @@ import face_recognition
import os
import sqlite3
import numpy as np
+from datetime import datetime
+import time
# 初始化摄像头
cap = cv2.VideoCapture(0)
-photo_count = 0
max_photos = 10
-captured_images = []
# 创建目录以保存照片
save_path = "./captured_faces"
os.makedirs(save_path, exist_ok=True)
-while photo_count < max_photos:
- ret, frame = cap.read()
- if not ret:
- break
-
- # 将图像转换为RGB颜色
- rgb_frame = frame[:, :, ::-1]
-
- # 检测人脸
- face_locations = face_recognition.face_locations(rgb_frame)
-
- for face_location in face_locations:
- top, right, bottom, left = face_location
-
- # 在图像上绘制绿框
- cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
-
- # 提取人脸区域
- face_image = frame[top:bottom, left:right]
-
- # 保存抓拍的照片
- image_path = os.path.join(save_path, f"face_{photo_count + 1}.jpg")
- cv2.imwrite(image_path, face_image)
- captured_images.append(image_path)
-
- photo_count += 1
- if photo_count >= max_photos:
- break
-
- # 显示结果
- cv2.imshow("Capturing Faces", frame)
- if cv2.waitKey(1) & 0xFF == ord('q'):
- break
-
-cap.release()
-cv2.destroyAllWindows()
-
-print(f"Captured {photo_count} images.")
def create_face_database(db_name="face_database.db"):
conn = sqlite3.connect(db_name)
@@ -59,11 +21,21 @@ def create_face_database(db_name="face_database.db"):
c.execute('''CREATE TABLE IF NOT EXISTS faces
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
+ identity TEXT NOT NULL,
encoding BLOB NOT NULL)''')
+
+ # 创建匹配日志表
+ c.execute('''CREATE TABLE IF NOT EXISTS match_logs
+ (id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL,
+ identity TEXT NOT NULL,
+ image_path TEXT NOT NULL,
+ match_time TEXT NOT NULL)''')
conn.commit()
conn.close()
-def add_face_to_database(name, image_path, db_name="face_database.db"):
+
+def add_face_to_database(name, identity, image_path, db_name="face_database.db"):
conn = sqlite3.connect(db_name)
c = conn.cursor()
@@ -75,17 +47,36 @@ def add_face_to_database(name, image_path, db_name="face_database.db"):
face_encoding = face_encodings[0]
# 将编码转换为可以存储的格式
encoding_blob = np.array(face_encoding).tobytes()
- c.execute("INSERT INTO faces (name, encoding) VALUES (?, ?)",
- (name, encoding_blob))
+ c.execute("INSERT INTO faces (name, identity, encoding) VALUES (?, ?, ?)",
+ (name, identity, encoding_blob))
conn.commit()
conn.close()
-def match_faces(captured_images, db_name="face_database.db", tolerance=0.4):
+
+def log_match(name, identity, image_path, db_name="face_database.db", log_file="match_log.txt"):
+ conn = sqlite3.connect(db_name)
+ c = conn.cursor()
+
+ # 获取当前时间
+ match_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+
+ # 将匹配信息插入到匹配日志表中
+ c.execute("INSERT INTO match_logs (name, identity, image_path, match_time) VALUES (?, ?, ?, ?)",
+ (name, identity, image_path, match_time))
+ conn.commit()
+ conn.close()
+
+ # 将匹配信息写入文本文件
+ with open(log_file, "a") as f:
+ f.write(f"匹配成功: {name} ({identity}) 在 {image_path} 时间: {match_time}\n")
+
+
+def match_faces(captured_images, db_name="face_database.db", tolerance=0.4, log_file="match_log.txt"):
conn = sqlite3.connect(db_name)
c = conn.cursor()
# 获取数据库中所有存储的人脸编码
- c.execute("SELECT name, encoding FROM faces")
+ c.execute("SELECT name, identity, encoding FROM faces")
known_faces = c.fetchall()
for image_path in captured_images:
@@ -99,16 +90,16 @@ def match_faces(captured_images, db_name="face_database.db", tolerance=0.4):
unknown_encoding = face_encodings[0]
- for name, encoding_blob in known_faces:
+ for name, identity, encoding_blob in known_faces:
known_encoding = np.frombuffer(encoding_blob, dtype=np.float64)
match = face_recognition.compare_faces([known_encoding], unknown_encoding, tolerance=tolerance)
if match[0]: # 如果匹配成功
- print(f"发现匹配: {name} 在 {image_path}")
+ print(f"发现匹配: {name} ({identity}) 在 {image_path}")
+ log_match(name, identity, image_path, db_name, log_file) # 记录匹配信息和时间到数据库和TXT文件
conn.close()
return True # 一旦找到匹配,返回成功
- else:
- print(f"没发现匹配: 在 {image_path}")
+ print(f"没发现匹配: 在 {image_path}")
conn.close()
return False # 如果所有比较都没有匹配,返回失败
@@ -116,10 +107,67 @@ def match_faces(captured_images, db_name="face_database.db", tolerance=0.4):
create_face_database()
# 向数据库中添加人脸
-add_face_to_database("屈礼", "./db_image/test.jpg")
+add_face_to_database("屈礼", "居民", "./db_image/test.jpg")
-# 逐张匹配抓拍的照片
-if match_faces(captured_images):
- print("至少一张匹配")
-else:
- print("没有匹配")
+# 主程序循环
+while True:
+ ret, frame = cap.read()
+ if not ret:
+ break
+
+ # 将图像转换为RGB颜色
+ rgb_frame = frame[:, :, ::-1]
+
+ # 检测人脸
+ face_locations = face_recognition.face_locations(rgb_frame)
+
+ if face_locations:
+ print("检测到人脸,开始抓拍...")
+
+ captured_images = []
+ photo_count = 0
+
+ while photo_count < max_photos:
+ ret, frame = cap.read()
+ if not ret:
+ break
+
+ rgb_frame = frame[:, :, ::-1]
+ face_locations = face_recognition.face_locations(rgb_frame)
+
+ for face_location in face_locations:
+ top, right, bottom, left = face_location
+
+ # 在图像上绘制绿框
+ cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
+
+ # 提取人脸区域
+ face_image = frame[top:bottom, left:right]
+
+ # 保存抓拍的照片
+ image_path = os.path.join(save_path, f"face_{photo_count + 1}.jpg")
+ cv2.imwrite(image_path, face_image)
+ captured_images.append(image_path)
+
+ photo_count += 1
+ if photo_count >= max_photos:
+ break
+
+ # 显示结果
+ cv2.imshow("Capturing Faces", frame)
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+ # 关闭窗口
+ cv2.destroyAllWindows()
+
+ if match_faces(captured_images):
+ print("至少一张匹配")
+ else:
+ print("没有匹配")
+
+ # 等待60秒后继续循环检测
+ print("等待30秒后继续...")
+ time.sleep(30)
+
+cap.release()
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..b785b75
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+ 匹配记录
+
+
+
+
+
Face Match Logs
+
+
+ Name |
+ Identity |
+ Image Path |
+ Match Time |
+
+ {% for log in logs %}
+
+ {{ log[0] }} |
+ {{ log[1] }} |
+ {{ log[2] }} |
+ {{ log[3] }} |
+
+ {% endfor %}
+
+
+
+