{"record":{"id":"b93a729feba92d25","repo":"lllyasviel/Fooocus","slug":"facial-pts-and-reference-pts-must-have-the-same-sh","errorCode":null,"errorMessage":"facial_pts and reference_pts must have the same shape","messagePattern":"facial_pts and reference_pts must have the same shape","errorType":"validation","errorClass":"FaceWarpException","httpStatus":null,"severity":"error","filePath":"extras/facexlib/detection/align_trans.py","lineNumber":208,"sourceCode":"\n    ref_pts = np.float32(reference_pts)\n    ref_pts_shp = ref_pts.shape\n    if max(ref_pts_shp) < 3 or min(ref_pts_shp) != 2:\n        raise FaceWarpException('reference_pts.shape must be (K,2) or (2,K) and K>2')\n\n    if ref_pts_shp[0] == 2:\n        ref_pts = ref_pts.T\n\n    src_pts = np.float32(facial_pts)\n    src_pts_shp = src_pts.shape\n    if max(src_pts_shp) < 3 or min(src_pts_shp) != 2:\n        raise FaceWarpException('facial_pts.shape must be (K,2) or (2,K) and K>2')\n\n    if src_pts_shp[0] == 2:\n        src_pts = src_pts.T\n\n    if src_pts.shape != ref_pts.shape:\n        raise FaceWarpException('facial_pts and reference_pts must have the same shape')\n\n    if align_type == 'cv2_affine':\n        tfm = cv2.getAffineTransform(src_pts[0:3], ref_pts[0:3])\n    elif align_type == 'affine':\n        tfm = get_affine_transform_matrix(src_pts, ref_pts)\n    else:\n        tfm = get_similarity_transform_for_cv2(src_pts, ref_pts)\n\n    face_img = cv2.warpAffine(src_img, tfm, (crop_size[0], crop_size[1]))\n\n    return face_img\n","sourceCodeStart":190,"sourceCodeEnd":220,"githubUrl":"https://github.com/lllyasviel/Fooocus/blob/ae05379cc97bc4361ec8b4ec90193dab21be763f/extras/facexlib/detection/align_trans.py#L190-L220","documentation":"After transposing both inputs to (K,2), warp_and_crop_face requires facial_pts and reference_pts to have identical shapes — a transform needs a 1:1 correspondence between source and target points. A landmark-count mismatch raises FaceWarpException.","triggerScenarios":"Combining a 5-point detector output (e.g. RetinaFace) with a reference layout built for a different number of points (68-point dlib layout, 98-point layout), or K mismatches after reshaping.","commonSituations":"Swapping landmark detectors without regenerating the reference points; mixing 5-point and 68-point pipelines; reference computed for a different crop size convention that changed K.","solutions":["Use reference points with the same K as the detector output (RetinaFace 5-point -> get_reference_facial_points output)","Convert landmark formats explicitly (e.g. 68->5 point subset) before alignment","Assert src_pts.shape == ref_pts.shape before calling warp_and_crop_face"],"exampleFix":"// before\nimg5 = warp_and_crop_face(img, retinaface_5pts, ref_68pts)\n\n// after\nref5 = get_reference_facial_points((512,512), 0.25, (0,0), True)\nimg5 = warp_and_crop_face(img, retinaface_5pts, ref5)","handlingStrategy":"validation","validationCode":"import numpy as np\nsrc = np.asarray(facial_pts, dtype=np.float32).reshape(-1, 2)\nref = np.asarray(reference_pts, dtype=np.float32).reshape(-1, 2)\nassert src.shape == ref.shape, f'point count mismatch: {src.shape} vs {ref.shape}'","typeGuard":null,"tryCatchPattern":"from extras.facexlib.detection.align_trans import FaceWarpException\ntry:\n    img = warp_and_crop_face(img, src, ref)\nexcept FaceWarpException:\n    skip_frame_and_log(img_id)  # fallback for bad detection","preventionTips":["Use one landmark convention (5-point) throughout the pipeline","Convert 68/98-point sets to 5-point before alignment","Assert equal point counts before transform estimation"],"tags":["facexlib","face-alignment","landmarks","shape-mismatch"],"backgroundTag":null,"analyzedSha":"ae05379cc97bc4361ec8b4ec90193dab21be763f","analyzedAt":"2026-08-15T04:23:59.533Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}