修改角度测量,延长二维码显示时间

This commit is contained in:
Tian jianyong 2025-12-18 14:50:03 +08:00
parent eb44c0a20e
commit 7766cfc9be
2 changed files with 77 additions and 28 deletions

View File

@ -21,7 +21,7 @@ websocket:
# 二维码设置
qrcode:
image_path: "preview_qrcode_sota.png" # 二维码图片路径
display_duration: 10 # 显示持续时间(秒)
display_duration: 30 # 显示持续时间(秒)
video:
path: "exhibition.mp4" # 视频文件路径

View File

@ -476,7 +476,23 @@ class FaceRecognitionSystem:
return Image.composite(top, base, mask)
def _draw_rounded_rect(self, draw, box, radius, fill, outline=None, width=0):
draw.rounded_rectangle(box, radius=radius, fill=fill, outline=outline, width=width)
# 兼容旧版本PIL手动绘制圆角矩形
x1, y1, x2, y2 = box
# 绘制主体部分
draw.rectangle([x1+radius, y1, x2-radius, y2], fill=fill, outline=outline, width=width)
draw.rectangle([x1, y1+radius, x2, y2-radius], fill=fill, outline=outline, width=width)
# 绘制四个角的圆弧
if radius > 0:
# 左上角
draw.ellipse([x1, y1, x1+2*radius, y1+2*radius], fill=fill, outline=outline, width=width)
# 右上角
draw.ellipse([x2-2*radius, y1, x2, y1+2*radius], fill=fill, outline=outline, width=width)
# 左下角
draw.ellipse([x1, y2-2*radius, x1+2*radius, y2], fill=fill, outline=outline, width=width)
# 右下角
draw.ellipse([x2-2*radius, y2-2*radius, x2, y2], fill=fill, outline=outline, width=width)
def _draw_shadow(self, image, box, radius, offset=(0, 4), blur=10, shadow_color=(0,0,0,50)):
# Create a separate shadow layer
@ -1242,38 +1258,71 @@ class FaceRecognitionSystem:
def detect_faces(self, frame: np.ndarray) -> Optional[Dict[str, Any]]:
"""检测人脸"""
try:
import requests
# 将帧编码为JPEG
_, img_encoded = cv2.imencode('.jpg', frame)
# 调用CompreFace检测API
result = self.detection_service.detect(img_encoded.tobytes())
if result and 'result' in result and len(result['result']) > 0:
faces = result['result']
# 过滤掉太小的人脸
min_size = self.config['face_detection']['min_face_size']
valid_faces = []
# 构建CompreFace REST API URL
api_url = f"{self.config['compreface']['host']}:{self.config['compreface']['port']}/api/v1/detection/detect"
# 准备请求参数
params = {
'face_plugins': 'pose' # 启用pose插件
}
# 准备请求头
headers = {
'x-api-key': self.config['compreface']['detection_api_key']
}
# 发送请求
files = {
'file': ('image.jpg', img_encoded.tobytes(), 'image/jpeg')
}
response = requests.post(api_url, headers=headers, files=files, params=params)
if response.status_code == 200:
result = response.json()
# 获取角度阈值
max_yaw = self.config['face_detection'].get('max_yaw', 30.0)
max_pitch = self.config['face_detection'].get('max_pitch', 30.0)
if result and 'result' in result and len(result['result']) > 0:
faces = result['result']
for face in faces:
# 检查人脸尺寸
face_width = face['box']['x_max'] - face['box']['x_min']
face_height = face['box']['y_max'] - face['box']['y_min']
# 过滤掉太小的人脸
min_size = self.config['face_detection']['min_face_size']
valid_faces = []
if face_width >= min_size and face_height >= min_size:
# 临时记录face数据查看是否有pose信息
self.logger.debug(f"检测到人脸数据: {list(face.keys())}")
if 'pose' in face:
self.logger.debug(f"Pose数据: {face['pose']}")
valid_faces.append(face)
# 获取角度阈值
max_yaw = self.config['face_detection'].get('max_yaw', 30.0)
max_pitch = self.config['face_detection'].get('max_pitch', 30.0)
if valid_faces:
# 返回第一个(最大的)人脸
return valid_faces[0]
for face in faces:
# 检查人脸尺寸
face_width = face['box']['x_max'] - face['box']['x_min']
face_height = face['box']['y_max'] - face['box']['y_min']
if face_width >= min_size and face_height >= min_size:
# 检查人脸角度
pose = face.get('pose', {})
yaw = pose.get('yaw', 0.0)
pitch = pose.get('pitch', 0.0)
# 记录pose数据
self.logger.debug(f"检测到人脸数据: {list(face.keys())}")
if 'pose' in face:
self.logger.debug(f"Pose数据: yaw={yaw:.1f}°, pitch={pitch:.1f}°, roll={pose.get('roll', 0.0):.1f}°")
# 判断是否为正脸
if abs(yaw) <= max_yaw and abs(pitch) <= max_pitch:
valid_faces.append(face)
self.logger.debug(f"人脸角度检查通过: yaw={yaw:.1f}°, pitch={pitch:.1f}°")
else:
self.logger.debug(f"人脸角度超出范围,跳过: yaw={yaw:.1f}°(阈值±{max_yaw}°), pitch={pitch:.1f}°(阈值±{max_pitch}°)")
if valid_faces:
# 返回第一个(最大的)人脸
return valid_faces[0]
return None