华荣三照明、合信、荣欣八组合馈电
This commit is contained in:
199
QT5_Project/Shared_CODE/run.py
Normal file
199
QT5_Project/Shared_CODE/run.py
Normal file
@ -0,0 +1,199 @@
|
||||
# - * - coding:utf - 8 - * -
|
||||
import os
|
||||
from flask import Flask, request, jsonify, render_template, url_for, send_from_directory
|
||||
import numpy as np
|
||||
import face_recognition
|
||||
from PIL import Image
|
||||
|
||||
# 初始化 Flask 应用
|
||||
app = Flask(__name__)
|
||||
|
||||
# 定义路径常量
|
||||
npy_file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'face_data/face_data.npy'))
|
||||
image_folder_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'face_data'))
|
||||
|
||||
# 加载 face_data 数据
|
||||
def load_face_data():
|
||||
print(f"加载人脸数据: {npy_file_path}") # 打印加载数据的路径
|
||||
if os.path.exists(npy_file_path):
|
||||
try:
|
||||
face_data = np.load(npy_file_path, allow_pickle=True).item()
|
||||
return face_data
|
||||
except Exception as e:
|
||||
print(f"加载人脸编码时出错: {e}")
|
||||
return {}
|
||||
print("人脸数据文件不存在。")
|
||||
return {}
|
||||
|
||||
# 保存 face_data 数据
|
||||
def save_face_data(face_data):
|
||||
print(f"保存人脸数据到: {npy_file_path}") # 打印保存数据的路径
|
||||
np.save(npy_file_path, face_data)
|
||||
print("人脸数据保存成功。")
|
||||
|
||||
# 获取图片的 URL
|
||||
def get_image_url(name):
|
||||
# 使用 Flask 的自定义路由返回图片
|
||||
return url_for('serve_face_image', filename=f'{name}.jpg')
|
||||
|
||||
# 获取图片的绝对路径
|
||||
def get_image_path(name):
|
||||
image_path = os.path.join(image_folder_path, f'{name}.jpg')
|
||||
return os.path.abspath(image_path) # 返回绝对路径
|
||||
|
||||
# 比较人脸编码之间的相似度
|
||||
def is_same_person(new_encoding, existing_encoding, threshold=0.5):
|
||||
"""
|
||||
判断两个人脸编码是否属于同一个人
|
||||
threshold: 距离小于该阈值认为是同一个人
|
||||
"""
|
||||
distance = np.linalg.norm(np.array(new_encoding) - np.array(existing_encoding))
|
||||
return distance < threshold
|
||||
|
||||
# 检查上传的图片是否有效
|
||||
def check_image_validity(file_path):
|
||||
try:
|
||||
img = Image.open(file_path)
|
||||
img.verify() # 验证图片是否有效
|
||||
return True
|
||||
except (IOError, SyntaxError):
|
||||
return False
|
||||
|
||||
# 保存图片为标准的 .jpg 格式
|
||||
def save_image_as_jpeg(file, file_path):
|
||||
img = Image.open(file)
|
||||
img.convert("RGB").save(file_path, "JPEG")
|
||||
|
||||
# 自定义路由来返回图片
|
||||
@app.route('/face_image/<filename>')
|
||||
def serve_face_image(filename):
|
||||
try:
|
||||
return send_from_directory(image_folder_path, filename)
|
||||
except Exception as e:
|
||||
return jsonify({"error": "Image not found"}), 404
|
||||
|
||||
# 检查并创建 image_folder_path
|
||||
if not os.path.exists(image_folder_path):
|
||||
print(f"创建人脸图片文件夹: {image_folder_path}") # 打印创建的文件夹路径
|
||||
os.makedirs(image_folder_path)
|
||||
|
||||
# 检查上传的图片是否有效
|
||||
def check_image_validity(file_path):
|
||||
try:
|
||||
img = Image.open(file_path)
|
||||
img.verify() # 验证图片是否有效
|
||||
print(f"图片 {file_path} 是有效的图像文件。")
|
||||
except (IOError, SyntaxError) as e:
|
||||
print(f"无效的图片文件: {file_path}, 错误信息: {e}")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
print("访问首页,加载已注册人脸...")
|
||||
face_data = load_face_data()
|
||||
faces_and_images = [
|
||||
{"name": name, "image": get_image_url(name)} # 使用统一的函数生成路径
|
||||
for name in face_data.keys()
|
||||
if os.path.exists(os.path.join(image_folder_path, f"{name}.jpg"))
|
||||
]
|
||||
print(f"加载的已注册人脸: {faces_and_images}") # 打印加载的所有人脸
|
||||
return render_template('index.html', faces_and_images=faces_and_images, error_message=None)
|
||||
|
||||
@app.route('/add_face', methods=['POST'])
|
||||
def add_face():
|
||||
print("接收到添加人脸请求...")
|
||||
face_data = load_face_data()
|
||||
if 'file' not in request.files or 'name' not in request.form:
|
||||
return jsonify({"error": "请求中缺少 'file' 或 'name' 参数。"}), 400
|
||||
|
||||
file = request.files['file']
|
||||
name = request.form['name']
|
||||
print(f"上传的人脸名称: {name}, 文件: {file.filename}")
|
||||
|
||||
try:
|
||||
image = face_recognition.load_image_file(file)
|
||||
face_encodings = face_recognition.face_encodings(image)
|
||||
|
||||
if not face_encodings:
|
||||
return jsonify({"error": "上传的图片中没有检测到人脸。"}), 400
|
||||
|
||||
new_face_encoding = face_encodings[0]
|
||||
existing_faces = [face_data[stored_name] for stored_name in face_data.keys()]
|
||||
|
||||
# 检查是否有已存在的相似编码
|
||||
for existing_encoding in existing_faces:
|
||||
if is_same_person(new_face_encoding, existing_encoding):
|
||||
return jsonify({"error": "已有相似的人脸编码,无法添加。"}), 400
|
||||
|
||||
# 检查是否已有相同名字的图片
|
||||
file_path = os.path.join(image_folder_path, f"{name}.jpg")
|
||||
if os.path.exists(file_path):
|
||||
return jsonify({"error": f"'{name}' 的图片已经存在。"}), 400
|
||||
|
||||
# 保存图片为 JPEG 格式
|
||||
save_image_as_jpeg(file, file_path)
|
||||
|
||||
# 检查图片是否有效
|
||||
if not check_image_validity(file_path):
|
||||
return jsonify({"error": "上传的图片无效或损坏。"}), 400
|
||||
|
||||
# 将人脸编码保存
|
||||
face_data[name] = new_face_encoding.tolist()
|
||||
save_face_data(face_data)
|
||||
|
||||
return jsonify({"success": "人脸添加成功。"}), 200
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({"error": f"发生错误: {str(e)}"}), 500
|
||||
|
||||
@app.route('/delete_face', methods=['POST'])
|
||||
def delete_face():
|
||||
print("接收到删除人脸请求...")
|
||||
face_data = load_face_data()
|
||||
name = request.form.get('name')
|
||||
|
||||
if not name:
|
||||
print("缺少 'name' 参数。")
|
||||
return jsonify({"error": "缺少 'name' 参数。"}), 400
|
||||
|
||||
if name not in face_data:
|
||||
print(f"未找到名为 '{name}' 的人脸数据。")
|
||||
return jsonify({"error": f"未找到名为 '{name}' 的人脸数据。"}), 404
|
||||
|
||||
try:
|
||||
# 删除面部数据
|
||||
del face_data[name]
|
||||
save_face_data(face_data)
|
||||
|
||||
# 删除图片
|
||||
image_path = os.path.join(image_folder_path, f"{name}.jpg")
|
||||
if os.path.exists(image_path):
|
||||
os.remove(image_path)
|
||||
print(f"成功删除图片: {image_path}")
|
||||
else:
|
||||
print(f"未找到图片文件: {image_path}")
|
||||
|
||||
print(f"成功删除人脸: {name}")
|
||||
return jsonify({"success": f"人脸 '{name}' 删除成功。"}), 200
|
||||
|
||||
except Exception as e:
|
||||
print(f"发生错误: {str(e)}")
|
||||
return jsonify({"error": f"发生错误: {str(e)}"}), 500
|
||||
|
||||
@app.route('/list_faces', methods=['GET'])
|
||||
def list_faces():
|
||||
print("获取已注册人脸列表...")
|
||||
face_data = load_face_data()
|
||||
faces_with_images = [
|
||||
{"name": name, "image": get_image_url(name)} # 使用统一的函数生成路径
|
||||
for name in face_data.keys()
|
||||
if os.path.exists(os.path.join(image_folder_path, f'{name}.jpg'))
|
||||
]
|
||||
print(f"已注册人脸列表: {faces_with_images}") # 打印已注册人脸
|
||||
return jsonify({"faces": faces_with_images}), 200
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("启动 Flask 应用...")
|
||||
app.run(host='0.0.0.0', port=5000, debug=False)
|
||||
Reference in New Issue
Block a user