Signed-off-by: sairate <sairate@sina.cn>

This commit is contained in:
sairate 2024-08-28 15:42:58 +08:00
parent 05e0e3055d
commit 56b405bef0
15 changed files with 65 additions and 34 deletions

View File

@ -7,6 +7,17 @@
<list default="true" id="c512d54a-7f5f-4cfb-af24-29d5821a33bf" name="更改" comment="Signed-off-by: sairate &lt;sairate@sina.cn&gt;">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/app.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_1.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_1.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_10.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_10.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_2.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_2.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_3.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_3.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_4.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_4.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_5.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_5.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_6.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_6.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_7.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_7.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_8.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_8.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/captured_faces/face_9.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/captured_faces/face_9.jpg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/face_database.db" beforeDir="false" afterPath="$PROJECT_DIR$/face_database.db" afterDir="false" />
<change beforePath="$PROJECT_DIR$/scanf_face.py" beforeDir="false" afterPath="$PROJECT_DIR$/scanf_face.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@ -72,7 +83,7 @@
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RunManager" selected="Python.run_programs">
<component name="RunManager" selected="Python.app">
<configuration name="index.html" type="JavascriptDebugType" temporary="true" nameIsGenerated="true" uri="http://localhost:63342/face/templates/index.html" useBuiltInWebServerPort="true">
<method v="2" />
</configuration>
@ -170,8 +181,8 @@
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.run_programs" />
<item itemvalue="Python.app" />
<item itemvalue="Python.run_programs" />
<item itemvalue="Python.scanf_face" />
<item itemvalue="JavaScript 调试.index.html" />
<item itemvalue="Python.match_face" />
@ -226,7 +237,7 @@
<workItem from="1724821991134" duration="19000" />
<workItem from="1724822043361" duration="2584000" />
<workItem from="1724825008350" duration="405000" />
<workItem from="1724828238928" duration="742000" />
<workItem from="1724828238928" duration="2438000" />
</task>
<task id="LOCAL-00001" summary="sairate">
<option name="closed" value="true" />
@ -281,11 +292,11 @@
<option name="LAST_COMMIT_MESSAGE" value="Signed-off-by: sairate &lt;sairate@sina.cn&gt;" />
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/face$run_programs.coverage" NAME="run_programs 覆盖结果" MODIFIED="1724828630241" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$run_programs.coverage" NAME="run_programs 覆盖结果" MODIFIED="1724830389566" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$sqlite.coverage" NAME="sqlite 覆盖结果" MODIFIED="1724310603865" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$match_face.coverage" NAME="match_face 覆盖结果" MODIFIED="1724314395402" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$app.coverage" NAME="app 覆盖结果" MODIFIED="1724825033889" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$scanf_face.coverage" NAME="scanf_face 覆盖结果" MODIFIED="1724824492242" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$app.coverage" NAME="app 覆盖结果" MODIFIED="1724830677403" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$scanf_face.coverage" NAME="scanf_face 覆盖结果" MODIFIED="1724830382139" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/face$add_face.coverage" NAME="add_face 覆盖结果" MODIFIED="1724311005030" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
</project>

74
app.py
View File

@ -4,12 +4,51 @@ import sqlite3
import os
import eventlet
import face_recognition
import numpy as np
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = './static/db_image' # 设置文件上传路径
app.config['UPLOAD_FOLDER'] = './static/db_image/' # 设置文件上传路径
socketio = SocketIO(app, async_mode='eventlet')
# 从数据库中获取匹配日志记录
def create_face_database(db_name="face_database.db"):
"""创建人脸数据库和匹配日志表"""
conn = sqlite3.connect(db_name)
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS faces
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
identity TEXT NOT NULL,
image_path 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, identity, image_path, db_name="face_database.db"):
"""将人脸信息添加到数据库"""
conn = sqlite3.connect(db_name)
c = conn.cursor()
# 将图片路径转换为相对路径
relative_image_path = os.path.relpath(image_path, start='./static')
image = face_recognition.load_image_file(image_path)
face_encodings = face_recognition.face_encodings(image)
if face_encodings:
face_encoding = face_encodings[0]
encoding_blob = np.array(face_encoding).tobytes()
c.execute("INSERT INTO faces (name, identity, image_path, encoding) VALUES (?, ?, ?, ?)",
(name, identity, relative_image_path, encoding_blob))
conn.commit()
conn.close()
def get_match_logs(db_name="face_database.db"):
conn = sqlite3.connect(db_name)
c = conn.cursor()
@ -18,13 +57,11 @@ def get_match_logs(db_name="face_database.db"):
conn.close()
return logs
# 首页,展示匹配记录
@app.route('/')
def index():
logs = get_match_logs()
return render_template('index.html', logs=logs)
# 人员信息页面展示人员信息并进行CRUD操作
@app.route('/info_person', methods=['GET', 'POST'])
def info_person():
conn = sqlite3.connect('face_database.db')
@ -37,26 +74,11 @@ def info_person():
identity = request.form['identity']
image = request.files['image_path']
# 保存上传的图片并生成编码
if image:
image_path = os.path.join(app.config['UPLOAD_FOLDER'], image.filename)
image.save(image_path)
# 使用face_recognition生成面部编码
loaded_image = face_recognition.load_image_file(image_path)
face_encodings = face_recognition.face_encodings(loaded_image)
if face_encodings:
encoding = ','.join(map(lambda x: format(x, 'b'), face_encodings[0]))
image_path = "db_image/"+image.filename # 仅保存文件名以便后续使用
else:
return "No face detected in the uploaded image."
else:
image_path = ""
encoding = ""
c.execute("INSERT INTO faces (name, identity, image_path, encoding) VALUES (?, ?, ?, ?)",
(name, identity, image_path, encoding))
add_face_to_database(name, identity, image_path)
return redirect(url_for('info_person'))
# 更新人员信息
elif 'update' in request.form:
@ -74,13 +96,12 @@ def info_person():
face_encodings = face_recognition.face_encodings(loaded_image)
if face_encodings:
encoding = ','.join(map(str, face_encodings[0])) # 将编码转换为字符串存储
image_path = image.filename # 仅保存文件名
encoding = np.array(face_encodings[0]).tobytes()
else:
return "No face detected in the uploaded image."
else:
image_path = request.form['current_image_path'] # 使用当前的图片路径
encoding = request.form['encoding'] # 使用现有的编码
image_path = request.form['current_image_path']
encoding = request.form['encoding']
c.execute("UPDATE faces SET name=?, identity=?, image_path=?, encoding=? WHERE id=?",
(name, identity, image_path, encoding, id))
@ -99,13 +120,11 @@ def info_person():
return render_template('info_person.html', persons=persons)
# 处理 WebSocket 连接
@socketio.on('connect')
def handle_connect():
print('Client connected')
emit('update', {'logs': get_match_logs()})
# 发送更新到客户端
def send_updates():
while True:
# 模拟实时数据更新
@ -113,5 +132,6 @@ def send_updates():
eventlet.sleep(5) # 每 5 秒发送一次更新
if __name__ == '__main__':
create_face_database() # Ensure the database is created
socketio.start_background_task(send_updates)
socketio.run(app, debug=True)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

BIN
static/test1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB