layout-parser icon indicating copy to clipboard operation
layout-parser copied to clipboard

Bug in detectron2 import, PILLOW version needs a fix

Open KalkulatorHere opened this issue 8 months ago • 1 comments


AttributeError Traceback (most recent call last) /tmp/ipykernel_578/1987038964.py in <cell line: 0>() 1 import layoutparser as lp 2 import detectron2 ----> 3 model = lp.models.Detectron2LayoutModel( 4 config_path ='lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config', # In model catalog 5 label_map ={0: "Text", 1: "Title", 2: "List", 3:"Table", 4:"Figure"}, # In modellabel_map

/usr/local/lib/python3.11/dist-packages/layoutparser/file_utils.py in getattr(self, name) 219 return self._objects[name] 220 if name in self._modules: --> 221 value = self._get_module(name) 222 elif name in self._class_to_module.keys(): 223 module = self._get_module(self._class_to_module[name])

/usr/local/lib/python3.11/dist-packages/layoutparser/file_utils.py in _get_module(self, module_name) 230 231 def _get_module(self, module_name: str): --> 232 return importlib.import_module("." + module_name, self.name) 233 234 def reduce(self):

/usr/lib/python3.11/importlib/init.py in import_module(name, package) 124 break 125 level += 1 --> 126 return _bootstrap._gcd_import(name[level:], package, level) 127 128

/usr/lib/python3.11/importlib/_bootstrap.py in _gcd_import(name, package, level)

/usr/lib/python3.11/importlib/_bootstrap.py in find_and_load(name, import)

/usr/lib/python3.11/importlib/_bootstrap.py in find_and_load_unlocked(name, import)

/usr/lib/python3.11/importlib/_bootstrap.py in _load_unlocked(spec)

/usr/lib/python3.11/importlib/_bootstrap_external.py in exec_module(self, module)

/usr/lib/python3.11/importlib/_bootstrap.py in _call_with_frames_removed(f, *args, **kwds)

/usr/local/lib/python3.11/dist-packages/layoutparser/models/init.py in 13 # limitations under the License. 14 ---> 15 from .detectron2.layoutmodel import Detectron2LayoutModel 16 from .paddledetection.layoutmodel import PaddleDetectionLayoutModel 17 from .effdet.layoutmodel import EfficientDetLayoutModel

/usr/local/lib/python3.11/dist-packages/layoutparser/models/detectron2/init.py in 16 # A trick learned from 17 # https://github.com/facebookresearch/detectron2/blob/62cf3a2b6840734d2717abdf96e2dd57ed6612a6/detectron2/checkpoint/init.py#L6 ---> 18 from .layoutmodel import Detectron2LayoutModel

/usr/local/lib/python3.11/dist-packages/layoutparser/models/detectron2/layoutmodel.py in 24 25 if is_detectron2_available(): ---> 26 import detectron2.engine 27 import detectron2.config 28

/usr/local/lib/python3.11/dist-packages/detectron2/engine/init.py in 9 # prefer to let hooks and defaults live in separate namespaces (therefore not in all) 10 # but still make them available here ---> 11 from .hooks import * 12 from .defaults import *

/usr/local/lib/python3.11/dist-packages/detectron2/engine/hooks.py in 17 18 import detectron2.utils.comm as comm ---> 19 from detectron2.evaluation.testing import flatten_results_dict 20 from detectron2.solver import LRMultiplier 21 from detectron2.utils.events import EventStorage, EventWriter

/usr/local/lib/python3.11/dist-packages/detectron2/evaluation/init.py in 1 # Copyright (c) Facebook, Inc. and its affiliates. ----> 2 from .cityscapes_evaluation import CityscapesInstanceEvaluator, CityscapesSemSegEvaluator 3 from .coco_evaluation import COCOEvaluator 4 from .rotated_coco_evaluation import RotatedCOCOEvaluator 5 from .evaluator import DatasetEvaluator, DatasetEvaluators, inference_context, inference_on_dataset

/usr/local/lib/python3.11/dist-packages/detectron2/evaluation/cityscapes_evaluation.py in 9 from PIL import Image 10 ---> 11 from detectron2.data import MetadataCatalog 12 from detectron2.utils import comm 13 from detectron2.utils.file_io import PathManager

/usr/local/lib/python3.11/dist-packages/detectron2/data/init.py in 1 # Copyright (c) Facebook, Inc. and its affiliates. ----> 2 from . import transforms # isort:skip 3 4 from .build import ( 5 build_batch_data_loader,

/usr/local/lib/python3.11/dist-packages/detectron2/data/transforms/init.py in 2 from fvcore.transforms.transform import Transform, TransformList # order them first 3 from fvcore.transforms.transform import * ----> 4 from .transform import * 5 from .augmentation import * 6 from .augmentation_impl import *

/usr/local/lib/python3.11/dist-packages/detectron2/data/transforms/transform.py in 34 35 ---> 36 class ExtentTransform(Transform): 37 """ 38 Extracts a subregion from the source image and scales it to the output size.

/usr/local/lib/python3.11/dist-packages/detectron2/data/transforms/transform.py in ExtentTransform() 44 """ 45 ---> 46 def init(self, src_rect, output_size, interp=Image.LINEAR, fill=0): 47 """ 48 Args:

AttributeError: module 'PIL.Image' has no attribute 'LINEAR'

KalkulatorHere avatar Jun 04 '25 06:06 KalkulatorHere

I solved this by monkeypatching PIL... I created layout_detector_patch.py with the following contents

"""Patch for PIL compatibility issues with older detectron2 versions."""

import PIL.Image

# Add missing LINEAR attribute for compatibility with detectron2 0.4
if not hasattr(PIL.Image, 'LINEAR'):
    PIL.Image.LINEAR = PIL.Image.BILINEAR

Then importing this patch before layoutparser:

# Apply PIL compatibility patch before importing layoutparser
from . import layout_detector_patch

import layoutparser as lp
import numpy as np
from PIL import Image

It's a little dirty, but allowed me to get on with my day 😉

jchillerup avatar Jun 06 '25 13:06 jchillerup