{"record":{"id":"759c8d9263b6868e","repo":"lllyasviel/Fooocus","slug":"must-have-output-size-outer-padding-some-scal","errorCode":null,"errorMessage":"Must have (output_size - outer_padding)= some_scale * (crop_size * (1.0 + inner_padding_factor)","messagePattern":"Must have \\(output_size - outer_padding\\)= some_scale \\* \\(crop_size \\* \\(1\\.0 \\+ inner_padding_factor\\)","errorType":"validation","errorClass":"FaceWarpException","httpStatus":null,"severity":"error","filePath":"extras/facexlib/detection/align_trans.py","lineNumber":96,"sourceCode":"\n    if ((inner_padding_factor > 0 or outer_padding[0] > 0 or outer_padding[1] > 0) and output_size is None):\n        output_size = tmp_crop_size * \\\n            (1 + inner_padding_factor * 2).astype(np.int32)\n        output_size += np.array(outer_padding)\n    if not (outer_padding[0] < output_size[0] and outer_padding[1] < output_size[1]):\n        raise FaceWarpException('Not (outer_padding[0] < output_size[0] and outer_padding[1] < output_size[1])')\n\n    # 1) pad the inner region according inner_padding_factor\n    if inner_padding_factor > 0:\n        size_diff = tmp_crop_size * inner_padding_factor * 2\n        tmp_5pts += size_diff / 2\n        tmp_crop_size += np.round(size_diff).astype(np.int32)\n\n    # 2) resize the padded inner region\n    size_bf_outer_pad = np.array(output_size) - np.array(outer_padding) * 2\n\n    if size_bf_outer_pad[0] * tmp_crop_size[1] != size_bf_outer_pad[1] * tmp_crop_size[0]:\n        raise FaceWarpException('Must have (output_size - outer_padding)'\n                                '= some_scale * (crop_size * (1.0 + inner_padding_factor)')\n\n    scale_factor = size_bf_outer_pad[0].astype(np.float32) / tmp_crop_size[0]\n    tmp_5pts = tmp_5pts * scale_factor\n    #    size_diff = tmp_crop_size * (scale_factor - min(scale_factor))\n    #    tmp_5pts = tmp_5pts + size_diff / 2\n    tmp_crop_size = size_bf_outer_pad\n\n    # 3) add outer_padding to make output_size\n    reference_5point = tmp_5pts + np.array(outer_padding)\n    tmp_crop_size = output_size\n\n    return reference_5point\n\n\ndef get_affine_transform_matrix(src_pts, dst_pts):\n    \"\"\"\n    Function:","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/lllyasviel/Fooocus/blob/ae05379cc97bc4361ec8b4ec90193dab21be763f/extras/facexlib/detection/align_trans.py#L78-L114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nget_reference_facial_points((256,256), 0, (0,0), True, output_size=(512,384))\n\n// after\nget_reference_facial_points((256,256), 0, (0,0), True, output_size=None)  # derives 512x512","handlingStrategy":"validation","validationCode":"import numpy as np\ncrop = np.asarray(crop_size, dtype=np.int32)\nsize_bf_pad = np.asarray(output_size) - 2 * np.asarray(outer_padding)\nassert size_bf_pad[0] * crop[1] == size_bf_pad[1] * crop[0], 'aspect ratio mismatch'\n# or simply derive: output_size = tuple(crop * (1 + 2*inner_padding_factor) + outer_padding)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["facexlib","face-alignment","aspect-ratio","argument-validation"],"backgroundTag":null,"analyzedSha":"ae05379cc97bc4361ec8b4ec90193dab21be763f","analyzedAt":"2026-08-15T04:23:59.533Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}