lllyasviel/Fooocus · error · FaceWarpException
Must have (output_size - outer_padding)= some_scale * (crop_
Error message
Must have (output_size - outer_padding)= some_scale * (crop_size * (1.0 + inner_padding_factor)
What it means
The reference 5-point layout must preserve the crop's aspect ratio: (output_size - outer_padding) must be a uniform scale of the crop size (after inner padding). The function checks size_bf_outer_pad[0]*crop[1] == size_bf_outer_pad[1]*crop[0]; a mismatch means the requested output stretches the face non-uniformly, which raises FaceWarpException.
Source
Thrown at extras/facexlib/detection/align_trans.py:96
if ((inner_padding_factor > 0 or outer_padding[0] > 0 or outer_padding[1] > 0) and output_size is None):
output_size = tmp_crop_size * \
(1 + inner_padding_factor * 2).astype(np.int32)
output_size += np.array(outer_padding)
if not (outer_padding[0] < output_size[0] and outer_padding[1] < output_size[1]):
raise FaceWarpException('Not (outer_padding[0] < output_size[0] and outer_padding[1] < output_size[1])')
# 1) pad the inner region according inner_padding_factor
if inner_padding_factor > 0:
size_diff = tmp_crop_size * inner_padding_factor * 2
tmp_5pts += size_diff / 2
tmp_crop_size += np.round(size_diff).astype(np.int32)
# 2) resize the padded inner region
size_bf_outer_pad = np.array(output_size) - np.array(outer_padding) * 2
if size_bf_outer_pad[0] * tmp_crop_size[1] != size_bf_outer_pad[1] * tmp_crop_size[0]:
raise FaceWarpException('Must have (output_size - outer_padding)'
'= some_scale * (crop_size * (1.0 + inner_padding_factor)')
scale_factor = size_bf_outer_pad[0].astype(np.float32) / tmp_crop_size[0]
tmp_5pts = tmp_5pts * scale_factor
# size_diff = tmp_crop_size * (scale_factor - min(scale_factor))
# tmp_5pts = tmp_5pts + size_diff / 2
tmp_crop_size = size_bf_outer_pad
# 3) add outer_padding to make output_size
reference_5point = tmp_5pts + np.array(outer_padding)
tmp_crop_size = output_size
return reference_5point
def get_affine_transform_matrix(src_pts, dst_pts):
"""
Function:View on GitHub (pinned to ae05379cc9)
Solutions
- Use an output_size with the same aspect ratio as the (inner-padded) crop, e.g. square crop -> square output
- Compute output_size from the documented relation: output_size = crop_size*(1+2*inner_padding_factor) + outer_padding (as the function itself does when output_size is None)
- Leave output_size=None and let the function derive the consistent size
Example fix
// before get_reference_facial_points((256,256), 0, (0,0), True, output_size=(512,384)) // after get_reference_facial_points((256,256), 0, (0,0), True, output_size=None) # derives 512x512
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np crop = np.asarray(crop_size, dtype=np.int32) size_bf_pad = np.asarray(output_size) - 2 * np.asarray(outer_padding) assert size_bf_pad[0] * crop[1] == size_bf_pad[1] * crop[0], 'aspect ratio mismatch' # or simply derive: output_size = tuple(crop * (1 + 2*inner_padding_factor) + outer_padding)
Prevention
- Prefer output_size=None and let the library derive it
- Keep crops and outputs square unless padding preserves ratio
- Compute output size with the documented formula instead of hardcoding
When it happens
Trigger: Requesting output_size=(512,384) for a square (e.g. 256x256) crop with symmetric padding — the proportions differ; any non-uniform resize baked into the alignment reference.
Common situations: Hardcoding rectangular output sizes for face restoration models that expect square input (GFPGAN uses 512x512); changing crop_size to non-square while keeping a square output_size; asymmetric outer_padding.
Related errors
- No paddings to do, output_size must be None or {}
- Not (0 <= inner_padding_factor <= 1.0)
- Not (outer_padding[0] < output_size[0] and outer_padding[1]
- reference_pts.shape must be (K,2) or (2,K) and K>2
- facial_pts.shape must be (K,2) or (2,K) and K>2
AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15).
Data as JSON: /api/errors/759c8d9263b6868e.
Report an issue: GitHub.