{"record":{"id":"7269386b8a896403","repo":"opendatalab/MinerU","slug":"the-ndim-img-ndim-of-the-img-is-not-in-2-3","errorCode":null,"errorMessage":"The ndim({img.ndim}) of the img is not in [2, 3]","messagePattern":"The ndim\\((.+?)\\) of the img is not in \\[2, 3\\]","errorType":"exception","errorClass":"LoadImageError","httpStatus":null,"severity":"error","filePath":"mineru/model/table/rec/unet_table/utils.py","lineNumber":135,"sourceCode":"        if img.ndim == 3:\n            channel = img.shape[2]\n            if channel == 1:\n                return cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)\n\n            if channel == 2:\n                return self.cvt_two_to_three(img)\n\n            if channel == 4:\n                return self.cvt_four_to_three(img)\n\n            if channel == 3:\n                return cv2.cvtColor(img, cv2.COLOR_RGB2BGR)\n\n            raise LoadImageError(\n                f\"The channel({channel}) of the img is not in [1, 2, 3, 4]\"\n            )\n\n        raise LoadImageError(f\"The ndim({img.ndim}) of the img is not in [2, 3]\")\n\n    @staticmethod\n    def cvt_four_to_three(img: np.ndarray) -> np.ndarray:\n        \"\"\"RGBA → BGR\"\"\"\n        r, g, b, a = cv2.split(img)\n        new_img = cv2.merge((b, g, r))\n\n        not_a = cv2.bitwise_not(a)\n        not_a = cv2.cvtColor(not_a, cv2.COLOR_GRAY2BGR)\n\n        new_img = cv2.bitwise_and(new_img, new_img, mask=a)\n        new_img = cv2.add(new_img, not_a)\n        return new_img\n\n    @staticmethod\n    def cvt_two_to_three(img: np.ndarray) -> np.ndarray:\n        \"\"\"gray + alpha → BGR\"\"\"\n        img_gray = img[..., 0]","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/model/table/rec/unet_table/utils.py#L117-L153","documentation":"convert_img's final guard: arrays must be 2-D (grayscale) or 3-D (multi-channel). ndim 1 (flattened vector), 4 (batched NCHW/NHWC), or higher raise LoadImageError with the actual ndim.","triggerScenarios":"Passing a batched array (1, H, W, 3) or a CHW tensor converted to numpy (3, H, W), or a flattened image vector (H*W,).","commonSituations":"Forgetting to squeeze a batch dimension, converting torch CHW tensors to numpy without transpose, or reshaping that collapses spatial dims.","solutions":["Batched NHWC: loop over img[0] or use img.squeeze(0) for batch size 1.","CHW from torch: arr = t.cpu().numpy().transpose(1, 2, 0).","Flattened: arr = arr.reshape(h, w)."],"exampleFix":"# before\nimg = loader(tensor.cpu().numpy())  # shape (3, H, W), ndim=3 but CHW is fine; (1,H,W,3) fails\n\n# after\narr = tensor.cpu().numpy()\nif arr.ndim == 4: arr = arr[0]\nif arr.shape[0] in (1, 3) and arr.ndim == 3: arr = arr.transpose(1, 2, 0)\nimg = loader(arr)","handlingStrategy":"validation","validationCode":"if img.ndim == 4:\n    img = img[0]\nif img.ndim == 3 and img.shape[0] in (1, 3) and img.shape[-1] not in (1, 3):\n    img = img.transpose(1, 2, 0)  # CHW -> HWC\nassert img.ndim in (2, 3)","typeGuard":"def is_hwc_image(img: np.ndarray) -> bool:\n    return img.ndim in (2, 3)","tryCatchPattern":"try:\n    img = loader(arr)\nexcept LoadImageError as e:\n    if 'ndim' in str(e):\n        raise ValueError(f'expected HWC image, got shape {arr.shape}') from e\n    raise","preventionTips":["Standardize on HWC uint8 numpy as the interchange format between stages.","squeeze batch dims at the point tensors leave torch.","Log shapes at stage boundaries during development."],"tags":["image-processing","numpy","batch","table-recognition"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}