from flask import Flask, request, jsonify import cv2 import dlib import numpy as np from scipy.spatial import distance app = Flask(__name__) # 加载 Dlib 的人脸检测器和关键点检测器 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") def get_face_landmarks(image): """ 获取图像中的人脸轮廓关键点 """ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces = detector(gray) if len(faces) == 0: return None # 只处理第一张人脸 face = faces[0] landmarks = predictor(gray, face) return np.array([[p.x, p.y] for p in landmarks.parts()]) def compare_contours(contour1, contour2): """ 比较两个轮廓的相似度,返回偏移评估值 """ if contour1 is None or contour2 is None: return None # 计算两个轮廓之间的欧氏距离 dist = distance.cdist(contour1, contour2, 'euclidean') # 返回平均偏移值 return np.mean(dist) @app.route('/upload', methods=['POST']) def upload_image(): """ 处理前端上传的照片,计算轮廓偏移值 """ if 'file' not in request.files: return jsonify({"error": "No file uploaded"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "No file selected"}), 400 # 读取上传的图像 image = cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR) if image is None: return jsonify({"error": "Failed to read image"}), 400 # 获取上传图像的人脸轮廓 uploaded_contour = get_face_landmarks(image) if uploaded_contour is None: return jsonify({"error": "No face detected in uploaded image"}), 400 # 读取标准图像 standard_image = cv2.imread("standard_face.jpg") if standard_image is None: return jsonify({"error": "Failed to read standard image"}), 400 # 获取标准图像的人脸轮廓 standard_contour = get_face_landmarks(standard_image) if standard_contour is None: return jsonify({"error": "No face detected in standard image"}), 400 # 比较两个轮廓 offset_value = compare_contours(uploaded_contour, standard_contour) if offset_value is None: return jsonify({"error": "Failed to compare contours"}), 400 # 返回偏移评估值 return jsonify({"offset_value": float(offset_value)}), 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)