{"record":{"id":"9349b3b36fa04e5d","repo":"opendatalab/MinerU","slug":"unsupported-image-type-for-pp-doclayoutv2-type-i","errorCode":null,"errorMessage":"Unsupported image type for PP-DocLayoutV2: {type(image)}","messagePattern":"Unsupported image type for PP-DocLayoutV2: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"mineru/model/layout/pp_doclayoutv2.py","lineNumber":955,"sourceCode":"        batch_size, sequence_length, _ = order_scores.shape\n        order_votes = order_scores.triu(diagonal=1).sum(dim=1) + (\n            1.0 - order_scores.transpose(1, 2)\n        ).tril(diagonal=-1).sum(dim=1)\n        order_pointers = torch.argsort(order_votes, dim=1)\n        order_seq = torch.empty_like(order_pointers)\n        ranks = torch.arange(sequence_length, device=order_pointers.device, dtype=order_pointers.dtype).expand(\n            batch_size, -1\n        )\n        order_seq.scatter_(1, order_pointers, ranks)\n        return order_seq\n\n    def _preprocess_single_image(self, image: Union[np.ndarray, Image.Image]) -> Tuple[torch.Tensor, Tuple[int, int]]:\n        if isinstance(image, np.ndarray):\n            pil_image = Image.fromarray(image)\n        elif isinstance(image, Image.Image):\n            pil_image = image\n        else:\n            raise TypeError(f\"Unsupported image type for PP-DocLayoutV2: {type(image)}\")\n\n        pil_image = pil_image.convert(\"RGB\")\n        target_size = pil_image.size[1], pil_image.size[0]\n        pixel_values = tvF.pil_to_tensor(pil_image)\n        pixel_values = tvF.resize(\n            pixel_values,\n            size=[self.imgsz[1], self.imgsz[0]],\n            interpolation=InterpolationMode.BICUBIC,\n            antialias=False,\n        )\n        pixel_values = pixel_values.to(dtype=torch.float32) * self.rescale_factor\n        return pixel_values, target_size\n\n    def _post_process_object_detection(\n        self,\n        outputs: PPDocLayoutV2ForObjectDetectionOutput,\n        target_sizes: Sequence[Tuple[int, int]],\n    ) -> List[Dict[str, torch.Tensor]]:","sourceCodeStart":937,"sourceCodeEnd":973,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/model/layout/pp_doclayoutv2.py#L937-L973","documentation":"TypeError raised by PPDocLayoutV2LayoutModel._preprocess_single_image when the image argument is neither a numpy ndarray nor a PIL Image. Preprocessing immediately converts to PIL for RGB conversion and tensor transforms, so any other type (str path, bytes, torch tensor, cv2 GPU mat) fails this isinstance check.","triggerScenarios":"predict(image='/data/page1.png'), predict(image=torch.Tensor(...)), or passing raw bytes from an HTTP response; also URLs or pathlib.Path objects.","commonSituations":"Users assuming the API accepts file paths (common with YOLO-style predict APIs); pipelines that read files with cv2 but pass a path variable by mistake; passing a tensor produced by an earlier preprocessing stage.","solutions":["Load the file first: PIL.Image.open(path) or cv2.imread(path) (ndarray is accepted).","Convert tensors: img = torchvision.transforms.functional.to_pil_image(tensor).","For bytes: io.BytesIO(data) wrapped in Image.open(...).","Check type before calling predict and normalize to ndarray/PIL."],"exampleFix":"# before\nmodel.predict(image='/data/page1.png')  # TypeError\n\n# after\nfrom PIL import Image\nmodel.predict(image=Image.open('/data/page1.png').convert('RGB'))","handlingStrategy":"type-guard","validationCode":"from PIL import Image\nimport numpy as np\n\ndef as_model_image(image):\n    if isinstance(image, Image.Image):\n        return image\n    if isinstance(image, np.ndarray):\n        return image\n    if isinstance(image, (str, bytes)):\n        return Image.open(image if isinstance(image, str) else __import__('io').BytesIO(image))\n    raise TypeError(f'unsupported image type {type(image)!r}')","typeGuard":"def is_supported_image(image) -> bool:\n    import numpy as np\n    from PIL import Image\n    return isinstance(image, (np.ndarray, Image.Image))","tryCatchPattern":"try:\n    model.predict(image=img)\nexcept TypeError as e:\n    if 'Unsupported image type' in str(e):\n        img = Image.open(img).convert('RGB')  # it was a path/bytes\n        model.predict(image=img)\n    else:\n        raise","preventionTips":["Open files with PIL (or cv2) before calling predict — paths are not accepted.","Centralize image loading in one adapter that returns ndarray/PIL.","Convert decoded bytes via io.BytesIO + Image.open at the boundary."],"tags":["pytorch","image-processing","type-error","layout-model"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}