cmvr-biohead/calibration.py
2025-08-21 13:49:41 +08:00

92 lines
2.6 KiB
Python

import cv2
import yaml
import numpy as np
import mediapipe as mp
import pyrealsense2 as rs
from collections import deque
from biohead.algo import *
from biohead.utils import calc_feature
def init_interval_dict():
interval = {}
for key in HeadJoints().to_dict().keys():
interval[key] = [np.inf, -np.inf]
return interval
def update_interval(interval, result):
for key, val in result.to_dict().items():
if key in interval:
pre_min, pre_max = interval[key]
cur_min = min(getattr(result, key), pre_min)
cur_max = max(getattr(result, key), pre_max)
interval[key] = [cur_min, cur_max]
def save_interval_yaml(interval, filename="./config/calibrated_interval.yaml"):
# Wrap in AngleInterval
out = {}
for k, v in interval.items():
out[k] = [float(v[0]), float(v[1])]
with open(filename, "w") as f:
yaml.dump(out, f)
def calibrate():
with open(r"./config/config.yaml", "r") as f:
config = yaml.load(f, Loader=yaml.FullLoader)
w, h, fps = config['Camera']['image_width'], config['Camera']['image_height'], config['Camera']['fps']
pipe = rs.pipeline()
cfg = rs.config()
cfg.enable_stream(rs.stream.color, w, h, rs.format.bgr8, fps)
pipe.start(cfg)
align = rs.align(rs.stream.color)
mp_mesh = mp.solutions.face_mesh
mesh = mp_mesh.FaceMesh(
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=config['MediaPipe']['min_detection_confidence'],
min_tracking_confidence=config['MediaPipe']['min_tracking_confidence']
)
ray_origins = deque(maxlen=config['Smooth'])
ray_directions = deque(maxlen=config['Smooth'])
interval = init_interval_dict()
while True:
frames = align.process(pipe.wait_for_frames())
color_f = frames.get_color_frame()
if not color_f: continue
color = np.asanyarray(color_f.get_data())
h, w, _ = color.shape
rgb = cv2.cvtColor(color, cv2.COLOR_BGR2RGB)
res = mesh.process(rgb)
if not res.multi_face_landmarks: continue
uv = calc_feature(color, res, ray_origins, ray_directions)
result = HeadJoints()
result = calc_eyebrow(uv, result)
result = calc_eyelid(uv, result)
result = calc_eyeball(uv, result)
result = calc_mouth(uv, result)
result = calc_jaw(uv, result)
update_interval(interval, result)
cv2.imshow("Calibration", color)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
pipe.stop()
cv2.destroyAllWindows()
save_interval_yaml(interval)
if __name__ == '__main__':
calibrate()