华荣三照明、合信、荣欣八组合馈电

This commit is contained in:
冯佳
2025-06-25 11:36:43 +08:00
parent 37d39f4578
commit 25b3cb7f2e
494 changed files with 114074 additions and 0 deletions

View 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)