{"record":{"id":"79f1e999ebb01b73","repo":"keras-team/keras","slug":"invalid-images-rank-expected-rank-4-batch-of-ima","errorCode":null,"errorMessage":"Invalid images rank: expected rank 4 (batch of images). Received: images.shape={images_shape}","messagePattern":"Invalid images rank: expected rank 4 \\(batch of images\\)\\. Received: images\\.shape=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/ops/image.py","lineNumber":2635,"sourceCode":"        translation,\n        spatial_dims,\n        method,\n        antialias,\n    )\n\n\nclass SobelEdges(Operation):\n    def __init__(self, data_format=None, *, name=None):\n        super().__init__(name=name)\n        self.data_format = backend.standardize_data_format(data_format)\n\n    def call(self, images):\n        return backend.image.sobel_edges(images, data_format=self.data_format)\n\n    def compute_output_spec(self, images):\n        images_shape = list(images.shape)\n        if len(images_shape) != 4:\n            raise ValueError(\n                \"Invalid images rank: expected rank 4 (batch of images). \"\n                f\"Received: images.shape={images_shape}\"\n            )\n        # Output adds an extra dimension of size 2 for [dy, dx]\n        output_shape = images_shape + [2]\n        return KerasTensor(shape=output_shape, dtype=images.dtype)\n\n\n@keras_export(\"keras.ops.image.sobel_edges\")\ndef sobel_edges(images, data_format=None):\n    \"\"\"Computes Sobel edge detection on images.\n\n    The Sobel operator computes the gradient of the image intensity at each\n    pixel, giving the direction of the largest increase from light to dark\n    and the rate of change in that direction.\n\n    Args:\n        images: Input tensor of shape `(batch, height, width, channels)` if","sourceCodeStart":2617,"sourceCodeEnd":2653,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/ops/image.py#L2617-L2653","documentation":"sobel_edges strictly requires a rank-4 batched tensor (N, H, W, C); unlike other image ops it rejects single rank-3 images. compute_output_spec appends a trailing size-2 axis for [dy, dx], which only makes sense for a batch.","triggerScenarios":"keras.ops.image.sobel_edges(single_image) with shape (H, W, C); passing (N, H, W) grayscale without channel or batch axes.","commonSituations":"Applying Sobel inside a per-example loop; feeding grayscale stored as (H, W) after squeeze; assuming rank-3 support because sibling ops allow it.","solutions":["Expand a single image to a batch: images[None, ...].","For (N, H, W) grayscale, add the channel axis too: images[..., None].","Remember the output is (N, H, W, C, 2)."],"exampleFix":"# before\nedges = keras.ops.image.sobel_edges(img)  # img: (H, W, C)\n\n# after\nedges = keras.ops.image.sobel_edges(img[None])[0]","handlingStrategy":"validation","validationCode":"import numpy as np\nx = np.asarray(images)\nif x.ndim == 3: x = x[np.newaxis]\nassert x.ndim == 4, x.shape","typeGuard":"def is_batched_nhwc(x):\n    return getattr(x, 'ndim', None) == 4","tryCatchPattern":null,"preventionTips":["Remember sobel_edges is batch-only, unlike most keras.image ops.","Wrap the op in a layer that adds the batch axis once."],"tags":["keras","image","sobel","shape-validation"],"backgroundTag":"tensor-rank-mismatch","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}