Extract grid helper; dedup calibrations

This commit is contained in:
ck-zhang
2025-04-30 16:07:21 +08:00
parent a5484733be
commit d15e4c9684
4 changed files with 35 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
from .common import wait_for_face_and_countdown
from .common import wait_for_face_and_countdown, compute_grid_points
from .nine_point import run_9_point_calibration
from .five_point import run_5_point_calibration
from .lissajous import run_lissajous_calibration
@@ -6,6 +6,7 @@ from .fine_tune import fine_tune_kalman_filter
__all__ = [
"wait_for_face_and_countdown",
"compute_grid_points",
"run_9_point_calibration",
"run_5_point_calibration",
"run_lissajous_calibration",

View File

@@ -3,9 +3,28 @@ import cv2
import numpy as np
def compute_grid_points(order, sw: int, sh: int, margin_ratio: float = 0.10):
"""
Translate grid (row, col) indices into absolute pixel locations
"""
if not order:
return []
max_r = max(r for r, _ in order)
max_c = max(c for _, c in order)
mx, my = int(sw * margin_ratio), int(sh * margin_ratio)
gw, gh = sw - 2 * mx, sh - 2 * my
step_x = 0 if max_c == 0 else gw / max_c
step_y = 0 if max_r == 0 else gh / max_r
return [(mx + int(c * step_x), my + int(r * step_y)) for r, c in order]
def wait_for_face_and_countdown(cap, gaze_estimator, sw, sh, dur: int = 2) -> bool:
"""
Waits for a face to be detected (not blinking), then shows a countdown ellipse.
Waits for a face to be detected (not blinking), then shows a countdown ellipse
"""
cv2.namedWindow("Calibration", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("Calibration", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
@@ -66,7 +85,7 @@ def _pulse_and_capture(
cd_d: float = 1.0,
):
"""
Shared pulse-and-capture loop for each calibration point.
Shared pulse-and-capture loop for each calibration point
"""
feats, targs = [], []

View File

@@ -2,7 +2,11 @@ import cv2
import numpy as np
from eyetrax.utils.screen import get_screen_size
from eyetrax.calibration.common import wait_for_face_and_countdown, _pulse_and_capture
from eyetrax.calibration.common import (
wait_for_face_and_countdown,
_pulse_and_capture,
compute_grid_points,
)
def run_5_point_calibration(gaze_estimator, camera_index: int = 0):
@@ -17,10 +21,8 @@ def run_5_point_calibration(gaze_estimator, camera_index: int = 0):
cv2.destroyAllWindows()
return
mx, my = int(sw * 0.1), int(sh * 0.1)
gw, gh = sw - 2 * mx, sh - 2 * my
order = [(1, 1), (0, 0), (2, 0), (0, 2), (2, 2)]
pts = [(mx + int(c * (gw / 2)), my + int(r * (gh / 2))) for (r, c) in order]
pts = compute_grid_points(order, sw, sh)
res = _pulse_and_capture(gaze_estimator, cap, pts, sw, sh)
cap.release()

View File

@@ -2,7 +2,11 @@ import cv2
import numpy as np
from eyetrax.utils.screen import get_screen_size
from eyetrax.calibration.common import wait_for_face_and_countdown, _pulse_and_capture
from eyetrax.calibration.common import (
wait_for_face_and_countdown,
_pulse_and_capture,
compute_grid_points,
)
def run_9_point_calibration(gaze_estimator, camera_index: int = 0):
@@ -17,8 +21,6 @@ def run_9_point_calibration(gaze_estimator, camera_index: int = 0):
cv2.destroyAllWindows()
return
mx, my = int(sw * 0.1), int(sh * 0.1)
gw, gh = sw - 2 * mx, sh - 2 * my
order = [
(1, 1),
(0, 0),
@@ -30,7 +32,7 @@ def run_9_point_calibration(gaze_estimator, camera_index: int = 0):
(2, 1),
(1, 2),
]
pts = [(mx + int(c * (gw / 2)), my + int(r * (gh / 2))) for (r, c) in order]
pts = compute_grid_points(order, sw, sh)
res = _pulse_and_capture(gaze_estimator, cap, pts, sw, sh)
cap.release()