def validate_image(image: np.ndarray) -> np.ndarray:
        """Validate the image array.

        Validates and normalizes input image arrays. Handles both RGB and grayscale
        images, and converts between channel-first and channel-last formats.

        Args:
            image (``np.ndarray``): Input image array to validate.

        Returns:
            ``np.ndarray``: Validated image array in channel-last format (H,W,C).

        Raises:
            TypeError: If ``image`` is not a numpy array.
            ValueError: If ``image`` dimensions or channels are invalid.

        Example:
            Validate RGB and grayscale images::

                >>> import numpy as np
                >>> from anomalib.data.validators import NumpyImageValidator
                >>> rgb_image = np.random.rand(256, 256, 3)
                >>> validated_rgb = NumpyImageValidator.validate_image(rgb_image)
                >>> validated_rgb.shape
                (256, 256, 3)
                >>> gray_image = np.random.rand(256, 256)
                >>> validated_gray = NumpyImageValidator.validate_image(gray_image)
                >>> validated_gray.shape
                (256, 256, 1)

        Note:
            - 2D arrays are treated as grayscale and expanded to 3D
            - Channel-first arrays (C,H,W) are converted to channel-last (H,W,C)
            - Output is always float32 type
        """
        if not isinstance(image, np.ndarray):
            msg = f"Image must be a numpy.ndarray, got {type(image)}."
            raise TypeError(msg)

        # Handle 2D grayscale images
        if image.ndim == 2:
            image = image[..., np.newaxis]

        if image.ndim != 3:
            msg = f"Image must have 2 or 3 dimensions, got shape {image.shape}."
            raise ValueError(msg)

        # Check if the image is in torch style (C, H, W) and rearrange if necessary
        if image.shape[0] in {1, 3} and image.shape[2] not in {1, 3}:
            image = np.transpose(image, (1, 2, 0))

        if image.shape[2] not in {1, 3}:
            msg = f"Image must have 1 or 3 channels, got {image.shape[2]}."
            raise ValueError(msg)

        return image.astype(np.float32)
Validate the image array.

        Validates and normalizes input image arrays. Handles both RGB and grayscale
        images, and converts between channel-first and channel-last formats.

        Args:
            image (``np.ndarray``): Input image array to validate.

        Returns:
            ``np.ndarray``: Validated image array in channel-last format (H,W,C).

        Raises:
            TypeError: If ``image`` is not a numpy array.
            ValueError: If ``image`` dimensions or channels are invalid.

        Example:
            Validate RGB and grayscale images::

                >>> import numpy as np
                >>> from anomalib.data.validators import NumpyImageValidator
                >>> rgb_image = np.random.rand(256, 256, 3)
                >>> validated_rgb = NumpyImageValidator.validate_image(rgb_image)
                >>> validated_rgb.shape
                (256, 256, 3)
                >>> gray_image = np.random.rand(256, 256)
                >>> validated_gray = NumpyImageValidator.validate_image(gray_image)
                >>> validated_gray.shape
                (256, 256, 1)

        Note:
            - 2D arrays are treated as grayscale and expanded to 3D
            - Channel-first arrays (C,H,W) are converted to channel-last (H,W,C)
            - Output is always float32 type
        
src/anomalib/data/validators/numpy/image.py