"""竖线坐标:与标注图同一套几何,接口1/6 的返回字段由此而来。""" import numpy as np from face_analysis.measure import MeasureResult from face_analysis.annotation import vertical_line_geometry def _result(): """已知像素坐标的测量结果。顶庭 2cm,不会触发发际线修正。""" vertical = { "hair_top": (500.0, 100.0), "hairline": (500.0, 200.2), "brow_center": (500.0, 350.0), "nose_bottom": (500.0, 500.0), "chin_tip": (500.0, 700.4), "top_court_px": 100.0, "upper_court_px": 150.0, "middle_court_px": 150.0, "lower_court_px": 200.0, } eyes = { "eye_width_px": 80.0, "face_width_px": 400.0, "inter_eye_distance_px": 90.0, "points": { "left_cheek": (300.4, 400.0), "left_outer": (360.6, 400.0), "left_inner": (440.2, 400.0), "right_inner": (530.8, 400.0), "right_outer": (610.4, 400.0), "right_cheek": (700.7, 400.0), }, } return MeasureResult(vertical, eyes, 50.0, "estimated", None) _INNER = [ "left_cheek", "left_eye_outer", "left_eye_inner", "right_eye_inner", "right_eye_outer", "right_cheek", ] def test_v1_inner_lines_and_extended_span(): geom = vertical_line_geometry(_result(), 1000, 800, variant="v1") # 短边 800,伸出 max(6, round(800*0.03)) = 24 assert geom["y_top"] == 76 assert geom["y_bottom"] == 724 assert [line["name"] for line in geom["lines"]] == _INNER assert [line["x"] for line in geom["lines"]] == [300, 361, 440, 531, 610, 701] def test_v6_span_is_hairline_to_chin_without_head_edges(): ear = np.zeros((800, 1000), dtype=np.uint8) ear[120:680, 250] = 255 ear[120:680, 760] = 255 geom = vertical_line_geometry( _result(), 1000, 800, ear_mask=ear, hair_mask=None, variant="v6") assert geom["y_top"] == 200 assert geom["y_bottom"] == 700 assert [line["name"] for line in geom["lines"]] == _INNER def test_v1_includes_ear_edges_left_to_right(): ear = np.zeros((800, 1000), dtype=np.uint8) ear[120:680, 250] = 255 ear[120:680, 760] = 255 geom = vertical_line_geometry( _result(), 1000, 800, ear_mask=ear, hair_mask=None, variant="v1") names = [line["name"] for line in geom["lines"]] xs = [line["x"] for line in geom["lines"]] assert names == ["left_head_edge", *_INNER, "right_head_edge"] assert xs[0] == 250 and xs[-1] == 760 assert xs == sorted(xs) def test_missing_ear_omits_that_edge(): ear = np.zeros((800, 1000), dtype=np.uint8) ear[120:680, 250] = 255 geom = vertical_line_geometry( _result(), 1000, 800, ear_mask=ear, hair_mask=None, variant="v1") names = [line["name"] for line in geom["lines"]] assert names[0] == "left_head_edge" assert "right_head_edge" not in names