{"record":{"id":"593d58297b5058ce","repo":"keras-team/keras","slug":"invalid-start-points-shape-expected-4-2-for-a-s-593d58","errorCode":null,"errorMessage":"Invalid start_points shape: expected (4,2) for a single image or (N,4,2) for a batch. Received shape: {start_points.shape}","messagePattern":"Invalid start_points shape: expected \\(4,2\\) for a single image or \\(N,4,2\\) for a batch\\. Received shape: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/image.py","lineNumber":2184,"sourceCode":"    def call(self, images, start_points, end_points):\n        return backend.image.perspective_transform(\n            images,\n            start_points,\n            end_points,\n            interpolation=self.interpolation,\n            fill_value=self.fill_value,\n            data_format=self.data_format,\n        )\n\n    def compute_output_spec(self, images, start_points, end_points):\n        if len(images.shape) not in (3, 4):\n            raise ValueError(\n                \"Invalid images rank: expected rank 3 (single image) \"\n                \"or rank 4 (batch of images). Received input with shape: \"\n                f\"images.shape={images.shape}\"\n            )\n        if start_points.shape[-2:] != (4, 2) or start_points.ndim not in (2, 3):\n            raise ValueError(\n                \"Invalid start_points shape: expected (4,2) for a single image\"\n                f\" or (N,4,2) for a batch. Received shape: {start_points.shape}\"\n            )\n        if end_points.shape[-2:] != (4, 2) or end_points.ndim not in (2, 3):\n            raise ValueError(\n                \"Invalid end_points shape: expected (4,2) for a single image\"\n                f\" or (N,4,2) for a batch. Received shape: {end_points.shape}\"\n            )\n        if start_points.shape != end_points.shape:\n            raise ValueError(\n                \"start_points and end_points must have the same shape.\"\n                f\" Received start_points.shape={start_points.shape}, \"\n                f\"end_points.shape={end_points.shape}\"\n            )\n        return KerasTensor(images.shape, dtype=images.dtype)\n\n\n@keras_export(\"keras.ops.image.perspective_transform\")","sourceCodeStart":2166,"sourceCodeEnd":2202,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/image.py#L2166-L2202","documentation":"In perspective's compute_output_spec, start_points must have trailing shape (4, 2) — the four corner (x, y) pairs — and overall ndim of 2 (single image) or 3 (batch). Any other layout, such as (2, 4), (8,), or (N, 2, 4), raises this error.","triggerScenarios":"keras.ops.image.perspective(img, start_points=np.array(...).reshape(2,4), ...); passing a flat list of 8 coordinates; transposing the corner matrix.","commonSituations":"Hand-built corner lists where x/y pairs got flattened or re-ordered; batching corners with shape (4, 2, N) instead of (N, 4, 2).","solutions":["Reshape start_points to exactly (4, 2) or (N, 4, 2).","Keep each row as one corner's (x, y); do not transpose to (2, 4).","For a batch, stack per-image (4, 2) arrays along a new leading axis."],"exampleFix":"# before\nstart_points = pts.reshape(2, 4)\n\n# after\nstart_points = pts.reshape(4, 2)","handlingStrategy":"type-guard","validationCode":"import numpy as np\nsp = np.asarray(start_points)\nif sp.ndim == 1 and sp.size == 8: sp = sp.reshape(4, 2)\nassert sp.ndim in (2, 3) and sp.shape[-2:] == (4, 2), sp.shape","typeGuard":"def valid_corner_points(p):\n    p = np.asarray(p)\n    return p.ndim in (2, 3) and tuple(p.shape[-2:]) == (4, 2)","tryCatchPattern":null,"preventionTips":["Build corners with one helper returning (4, 2).","Never transpose corner arrays; row = corner, columns = (x, y)."],"tags":["keras","image","perspective","shape-validation"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}