keras-team/keras · error · ValueError
start_points and end_points must have the same shape. Receiv
Error message
start_points and end_points must have the same shape. Received start_points.shape={start_points.shape}, end_points.shape={end_points.shape} What it means
perspective requires start_points and end_points to have identical shapes so each source corner maps to one destination corner. Mismatched batch sizes, or one array batched while the other is single-image, triggers this.
Source
Thrown at keras/src/ops/image.py:2194
def compute_output_spec(self, images, start_points, end_points):
if len(images.shape) not in (3, 4):
raise ValueError(
"Invalid images rank: expected rank 3 (single image) "
"or rank 4 (batch of images). Received input with shape: "
f"images.shape={images.shape}"
)
if start_points.shape[-2:] != (4, 2) or start_points.ndim not in (2, 3):
raise ValueError(
"Invalid start_points shape: expected (4,2) for a single image"
f" or (N,4,2) for a batch. Received shape: {start_points.shape}"
)
if end_points.shape[-2:] != (4, 2) or end_points.ndim not in (2, 3):
raise ValueError(
"Invalid end_points shape: expected (4,2) for a single image"
f" or (N,4,2) for a batch. Received shape: {end_points.shape}"
)
if start_points.shape != end_points.shape:
raise ValueError(
"start_points and end_points must have the same shape."
f" Received start_points.shape={start_points.shape}, "
f"end_points.shape={end_points.shape}"
)
return KerasTensor(images.shape, dtype=images.dtype)
@keras_export("keras.ops.image.perspective_transform")
def perspective_transform(
images,
start_points,
end_points,
interpolation="bilinear",
fill_value=0,
data_format=None,
):
"""Applies a perspective transformation to the image(s).
View on GitHub (pinned to 7a34a03db6)
Solutions
- Make both arrays the same shape: either both (4, 2) or both (N, 4, 2) with equal N.
- Tile/repeat the single-image array to batch size when it is constant.
- Assert start_points.shape == end_points.shape before the call.
Example fix
# before perspective(imgs, starts, ends[:4]) # ends has 8 entries # after ends = np.stack([base] * len(imgs)) perspective(imgs, starts, ends)
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np sp, ep = np.asarray(start_points), np.asarray(end_points) if sp.ndim == 2 and ep.ndim == 3: sp = np.stack([sp] * ep.shape[0]) assert sp.shape == ep.shape, (sp.shape, ep.shape)
Type guard
def matching_corner_points(sp, ep):
sp, ep = np.asarray(sp), np.asarray(ep)
return sp.shape == ep.shape and sp.shape[-2:] == (4, 2) Prevention
- Broadcast constant corners explicitly with np.stack.
- Keep source and destination corner lists generated in the same loop.
When it happens
Trigger: start_points.shape=(4,2) with end_points.shape=(8,4,2); a batch of N source corners but M != N destination corners.
Common situations: Broadcasting expectations carried over from NumPy conventions; per-image corners generated in a loop with an off-by-one; some images dropped from one list.
Related errors
- Invalid start_points shape: expected (4,2) for a single imag
- Invalid end_points shape: expected (4,2) for a single image
- Invalid images rank: expected rank 4 (batch of images). Rece
- Invalid image1 rank: expected rank 3 (single image) or rank
- Invalid image2 rank: expected rank 3 (single image) or rank
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/9a903ab6cbe499eb.
Report an issue: GitHub.