再投影誤差による破綻フレームの除外および窓の時間指定の実装と実験陽設定の更新
This commit is contained in:
1 parent
d042ef9790
commit
ca10876101
10 files changed
+256
-30
No files matched your search
+15
-2
@@ -55,6 +55,8 @@ class HeadPoseEstimator:
|
||||
image_points = self.build_image_points(landmarks)
|
||||
if image_points is None:
|
||||
return HeadPoseEstimation(False, failure_reason="insufficient_landmarks")
|
||||
# Outer eye corners (landmarks 33 and 263) are model points 2 and 3.
|
||||
eye_distance = math.hypot(image_points[3][0] - image_points[2][0], image_points[3][1] - image_points[2][1])
|
||||
try:
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -74,13 +76,24 @@ class HeadPoseEstimator:
|
||||
error = float(np.sqrt(np.mean(np.sum((projected.reshape(-1, 2) - image) ** 2, axis=1))))
|
||||
except Exception:
|
||||
return HeadPoseEstimation(False, failure_reason="solvepnp_failed")
|
||||
return self.result_from_angles(angles, error)
|
||||
return self.result_from_angles(angles, error, eye_distance_px=eye_distance)
|
||||
|
||||
def result_from_angles(
|
||||
self, angles: tuple[float, float, float], reprojection_error: float | None = None,
|
||||
eye_distance_px: float | None = None,
|
||||
) -> HeadPoseEstimation:
|
||||
"""Validate calculated angles and construct a normalized result."""
|
||||
"""Validate calculated angles and construct a normalized result.
|
||||
|
||||
When ``max_reprojection_error_ratio`` is set, a pose whose reprojection error
|
||||
exceeds that multiple of ``eye_distance_px`` is rejected: it is a degenerate
|
||||
solution (typically a very small or leaving face), not a noisy measurement.
|
||||
"""
|
||||
normalized = self.normalize_angles(angles)
|
||||
ratio = self.config.max_reprojection_error_ratio
|
||||
if (ratio > 0.0 and reprojection_error is not None and eye_distance_px is not None
|
||||
and eye_distance_px > 0.0 and reprojection_error > ratio * eye_distance_px):
|
||||
return HeadPoseEstimation(False, *normalized, reprojection_error=reprojection_error,
|
||||
failure_reason="reprojection_error_too_large")
|
||||
if any(not math.isfinite(value) or abs(value) > self.config.max_abs_angle for value in normalized):
|
||||
return HeadPoseEstimation(False, *normalized, reprojection_error=reprojection_error,
|
||||
failure_reason="angle_out_of_range")
|
||||
|
||||
Reference in new issue
Block a user