lllyasviel/Fooocus · error · FaceWarpException
reference_pts.shape must be (K,2) or (2,K) and K>2
Error message
reference_pts.shape must be (K,2) or (2,K) and K>2
What it means
Before estimating the alignment transform, the code normalizes reference_pts to shape (K,2) with K>2 (at least 3 point pairs are needed for an affine/similarity transform). If the array's larger dim is <3 or the smaller dim is not exactly 2, the shape is not a valid 2-D point set and FaceWarpException is raised.
Source
Thrown at extras/facexlib/detection/align_trans.py:194
@face_img: output face image with size (w, h) = @crop_size
"""
if reference_pts is None:
if crop_size[0] == 96 and crop_size[1] == 112:
reference_pts = REFERENCE_FACIAL_POINTS
else:
default_square = False
inner_padding_factor = 0
outer_padding = (0, 0)
output_size = crop_size
reference_pts = get_reference_facial_points(output_size, inner_padding_factor, outer_padding,
default_square)
ref_pts = np.float32(reference_pts)
ref_pts_shp = ref_pts.shape
if max(ref_pts_shp) < 3 or min(ref_pts_shp) != 2:
raise FaceWarpException('reference_pts.shape must be (K,2) or (2,K) and K>2')
if ref_pts_shp[0] == 2:
ref_pts = ref_pts.T
src_pts = np.float32(facial_pts)
src_pts_shp = src_pts.shape
if max(src_pts_shp) < 3 or min(src_pts_shp) != 2:
raise FaceWarpException('facial_pts.shape must be (K,2) or (2,K) and K>2')
if src_pts_shp[0] == 2:
src_pts = src_pts.T
if src_pts.shape != ref_pts.shape:
raise FaceWarpException('facial_pts and reference_pts must have the same shape')
if align_type == 'cv2_affine':
tfm = cv2.getAffineTransform(src_pts[0:3], ref_pts[0:3])
elif align_type == 'affine':View on GitHub (pinned to ae05379cc9)
Solutions
- Reshape reference points to (K,2) with K>=3, e.g. np.array(pts).reshape(-1,2)
- Prefer using the built-in get_reference_facial_points(...) output rather than hand-built arrays
- Validate shape before calling: assert arr.ndim == 2 and min(arr.shape) == 2 and max(arr.shape) >= 3
Example fix
// before ref = np.array([x1,y1,x2,y2,x3,y3,x4,y4,x5,y5]) # shape (10,) // after ref = np.array([x1,y1,x2,y2,x3,y3,x4,y4,x5,y5]).reshape(5,2)
Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
ref = np.asarray(reference_pts, dtype=np.float32)
assert ref.ndim == 2 and min(ref.shape) == 2 and max(ref.shape) >= 3, \
'reference_pts must be (K,2)/(2,K) with K>2' Type guard
def is_valid_point_set(pts) -> bool:
import numpy as np
a = np.asarray(pts)
return a.ndim == 2 and min(a.shape) == 2 and max(a.shape) >= 3 Prevention
- Always reshape landmarks to (K,2) at the boundary
- Generate reference points with get_reference_facial_points instead of hand-building
- Add shape asserts in tests for landmark pipelines
When it happens
Trigger: Passing reference_pts as a flat array of 10 values, a (5,) vector, a (1,2) single point, or a 3-D array; i.e. anything whose shape doesn't reduce to (K,2)/(2,K) with K>=3.
Common situations: Loading reference landmarks from JSON/config that flattened them; slicing mistakes (pts[0] instead of pts); detector outputting a different landmark count or layout than expected.
Related errors
- facial_pts.shape must be (K,2) or (2,K) and K>2
- facial_pts and reference_pts must have the same shape
- cp2tform:twoUniquePointsReq
- No paddings to do, output_size must be None or {}
- Not (0 <= inner_padding_factor <= 1.0)
AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15).
Data as JSON: /api/errors/6b081fddb3877064.
Report an issue: GitHub.