Signed-off-by: sairate <sairate@sina.cn>
|
@ -7,6 +7,17 @@
|
|||
<list default="true" id="c512d54a-7f5f-4cfb-af24-29d5821a33bf" name="更改" comment="Signed-off-by: sairate <sairate@sina.cn>">
|
||||
<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 @@
|
|||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</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 <sairate@sina.cn>" />
|
||||
</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
|
@ -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)
|
||||
|
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
BIN
face_database.db
|
@ -108,7 +108,7 @@ def log_match(name, identity, db_image_path, db_name, log_file):
|
|||
# create_face_database()
|
||||
#
|
||||
# # 向数据库中添加人脸
|
||||
# add_face_to_database("李四", "居民", "./static/db_image/test1.jpg")
|
||||
#add_face_to_database("李四", "居民", "./static/db_image/test1.jpg")
|
||||
# add_face_to_database("张三", "居民", "./static/db_image/test2.jpg")
|
||||
# add_face_to_database("王五", "居民", "./static/db_image/test3.jpg")
|
||||
|
||||
|
|
After Width: | Height: | Size: 36 KiB |