lllyasviel/Fooocus · error · Exception

cp2tform:twoUniquePointsReq

Error message

cp2tform:twoUniquePointsReq

What it means

In findNonreflectiveTransform (MATLAB cp2tform port), a similarity transform is solved from point correspondences via least squares; the system matrix X must have rank >= 2K (K=2 here, so rank >= 4), which requires the points to contain at least two distinct points. If all source points coincide (or are collinear in the degenerate sense that drops rank), the system is underdetermined and this Exception is raised.

Source

Thrown at extras/facexlib/detection/matlab_cp2tform.py:81

    K = options['K']
    M = xy.shape[0]
    x = xy[:, 0].reshape((-1, 1))  # use reshape to keep a column vector
    y = xy[:, 1].reshape((-1, 1))  # use reshape to keep a column vector

    tmp1 = np.hstack((x, y, np.ones((M, 1)), np.zeros((M, 1))))
    tmp2 = np.hstack((y, -x, np.zeros((M, 1)), np.ones((M, 1))))
    X = np.vstack((tmp1, tmp2))

    u = uv[:, 0].reshape((-1, 1))  # use reshape to keep a column vector
    v = uv[:, 1].reshape((-1, 1))  # use reshape to keep a column vector
    U = np.vstack((u, v))

    # We know that X * r = U
    if rank(X) >= 2 * K:
        r, _, _, _ = lstsq(X, U, rcond=-1)
        r = np.squeeze(r)
    else:
        raise Exception('cp2tform:twoUniquePointsReq')
    sc = r[0]
    ss = r[1]
    tx = r[2]
    ty = r[3]

    Tinv = np.array([[sc, -ss, 0], [ss, sc, 0], [tx, ty, 1]])
    T = inv(Tinv)
    T[:, 2] = np.array([0, 0, 1])

    return T, Tinv


def findSimilarity(uv, xy, options=None):
    options = {'K': 2}

    #    uv = np.array(uv)
    #    xy = np.array(xy)

View on GitHub (pinned to ae05379cc9)

Solutions

  1. Validate landmarks before transform estimation: at least 2 unique points, e.g. len(np.unique(pts, axis=0)) >= 2
  2. Filter out detections with degenerate landmark sets (all-identical or zero coordinates) and skip/retry that frame
  3. Fix the upstream detector/parsing step if it emits repeated points

Example fix

// before
tfm = get_similarity_transform_for_cv2(src_pts, ref_pts)  # src_pts all identical

// after
if len(np.unique(np.round(src_pts, 4), axis=0)) < 2:
    raise ValueError('degenerate landmarks: need >=2 unique points')
tfm = get_similarity_transform_for_cv2(src_pts, ref_pts)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
def has_two_unique_points(pts, tol=4):
    a = np.asarray(pts, dtype=np.float64)
    return a.ndim == 2 and len(np.unique(np.round(a, tol), axis=0)) >= 2

Try / catch

try:
    tfm = get_similarity_transform_for_cv2(src, ref)
except Exception as e:
    if 'twoUniquePointsReq' in str(e):
        handle_degenerate_detection()  # skip frame / re-detect
    else:
        raise

Prevention

When it happens

Trigger: Estimating a similarity transform where all src_pts are the same coordinate (detector returned garbage/zero landmarks), or fewer than 2 unique points were passed — the stacked linear system cannot determine sc, ss, tx, ty.

Common situations: Face detector confidence failure returning zeros or repeated points; landmark parsing bug filling every row with the same point; passing an empty/duplicated array into get_similarity_transform.

Related errors


AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15). Data as JSON: /api/errors/aa8fcbd45a047f3a. Report an issue: GitHub.