"""단독 프로세스로 FaceLandmarker를 실행해 478 랜드마크를 JSON으로 출력한다. (같은 프로세스에서 ImageSegmenter와 함께 쓰면 세그폴트가 재현되어 분리했다.) 사용: python _run_face_landmarks.py <이미지경로> <출력json경로> """ from __future__ import annotations import json import sys from pathlib import Path import mediapipe as mp import numpy as np from mediapipe.tasks import python as mp_python from mediapipe.tasks.python import vision from PIL import Image MODEL_FACE = Path(__file__).resolve().parent / "_models" / "face_landmarker.task" def main() -> int: image_path = Path(sys.argv[1]) out_path = Path(sys.argv[2]) base_options = mp_python.BaseOptions(model_asset_path=str(MODEL_FACE)) options = vision.FaceLandmarkerOptions( base_options=base_options, running_mode=vision.RunningMode.IMAGE, num_faces=1 ) im = Image.open(image_path).convert("RGB") w, h = im.size arr = np.array(im) mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=arr) with vision.FaceLandmarker.create_from_options(options) as landmarker: result = landmarker.detect(mp_image) if not result.face_landmarks: out_path.write_text(json.dumps({"ok": False}), encoding="utf-8") print("FACE_LANDMARKS_FAILED") return 1 lm = result.face_landmarks[0] pts = [[p.x * w, p.y * h] for p in lm] out_path.write_text(json.dumps({"ok": True, "width": w, "height": h, "points": pts}), encoding="utf-8") print(f"FACE_LANDMARKS_OK n={len(pts)}") return 0 if __name__ == "__main__": sys.exit(main())