Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inference_segmentor Fails on list of NDarrays #1643

Closed
alexgoft opened this issue Jun 6, 2022 · 6 comments
Closed

inference_segmentor Fails on list of NDarrays #1643

alexgoft opened this issue Jun 6, 2022 · 6 comments

Comments

@alexgoft
Copy link

alexgoft commented Jun 6, 2022

I'm trying to run the segmentor on a list of images (NDArrays) via the function inference_segmentor. It seems, at according to the function description, that it's possible:

def inference_segmentor(model, img):
    """Inference image(s) with the segmentor.

    Args:
        model (nn.Module): The loaded segmentor.
        imgs (str/ndarray or list[str/ndarray]): Either image files or loaded
            images.

    Returns:
        (list[Tensor]): The segmentation result.
    """
    cfg = model.cfg
    device = next(model.parameters()).device  # model device
    # build the data pipeline
    test_pipeline = [LoadImage()] + cfg.data.test.pipeline[1:]
    
    test_pipeline = Compose(test_pipeline)
    # prepare data
    data = dict(img=img)
    data = test_pipeline(data)
    data = collate([data], samples_per_gpu=1)
    if next(model.parameters()).is_cuda:
        # scatter to specified GPU
        data = scatter(data, [device])[0]
    else:
        data['img_metas'] = [i.data[0] for i in data['img_metas']]

    # forward the model
    with torch.no_grad():
        result = model(return_loss=False, rescale=True, **data)
    return result

However, i get the following error:

  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/apis/inference.py", line 89, in inference_segmentor
    data = test_pipeline(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/compose.py", line 41, in __call__
    data = t(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/apis/inference.py", line 63, in __call__
    img = mmcv.imread(results['img'])
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmcv/image/io.py", line 206, in imread
    raise TypeError('"img" must be a numpy array or a str or '
TypeError: "img" must be a numpy array or a str or a pathlib.Path object

When removing [LoadImage()] from test_pipeline in the code above, this error replaced with:

  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/apis/inference.py", line 89, in inference_segmentor
    data = test_pipeline(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/compose.py", line 41, in __call__
    data = t(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/test_time_aug.py", line 120, in __call__
    data = self.transforms(_results)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/compose.py", line 41, in __call__
    data = t(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/transforms.py", line 285, in __call__
    self._resize_img(results)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/transforms.py", line 241, in _resize_img
    img, scale_factor = mmcv.imrescale(
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmcv/image/geometric.py", line 242, in imrescale
    h, w = img.shape[:2]
AttributeError: 'list' object has no attribute 'shape'

The configuration used:

norm_cfg = dict(type='BN', requires_grad=True)
model = dict(
    type='EncoderDecoder',
    pretrained='open-mmlab:https://msra/hrnetv2_w48',
    backbone=dict(
        type='HRNet',
        norm_cfg=dict(type='SyncBN', requires_grad=True),
        norm_eval=False,
        extra=dict(
            stage1=dict(
                num_modules=1,
                num_branches=1,
                block='BOTTLENECK',
                num_blocks=(4, ),
                num_channels=(64, )),
            stage2=dict(
                num_modules=1,
                num_branches=2,
                block='BASIC',
                num_blocks=(4, 4),
                num_channels=(48, 96)),
            stage3=dict(
                num_modules=4,
                num_branches=3,
                block='BASIC',
                num_blocks=(4, 4, 4),
                num_channels=(48, 96, 192)),
            stage4=dict(
                num_modules=3,
                num_branches=4,
                block='BASIC',
                num_blocks=(4, 4, 4, 4),
                num_channels=(48, 96, 192, 384)))),
    decode_head=dict(
        type='FCNHead',
        in_channels=[48, 96, 192, 384],
        in_index=(0, 1, 2, 3),
        channels=720,
        input_transform='resize_concat',
        kernel_size=1,
        num_convs=1,
        concat_input=False,
        dropout_ratio=-1,
        num_classes=2,
        norm_cfg=dict(type='SyncBN', requires_grad=True),
        align_corners=False,
        loss_decode=dict(
            type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)),
    train_cfg=dict(),
    test_cfg=dict(mode='whole'))

data = dict(
    samples_per_gpu=1,
    workers_per_gpu=1,

    test=dict(
        type='CityscapesDataset',
        data_root='data/cityscapes/',
        img_dir='leftImg8bit/val',
        ann_dir='gtFine/val',
        pipeline=[
            dict(type='LoadImageFromFile'),
            dict(
                type='MultiScaleFlipAug',
                img_scale=(2048, 1024),
                flip=False,
                transforms=[
                    dict(type='Resize', keep_ratio=True),
                    dict(type='RandomFlip'),
                    dict(
                        type='Normalize',
                        mean=[123.675, 116.28, 103.53],
                        std=[58.395, 57.12, 57.375],
                        to_rgb=True),
                    dict(type='ImageToTensor', keys=['img']),
                    dict(type='Collect', keys=['img'])
                ])
        ])
)

What am I doing wrong? it seems that inference on a list of images is not really supported.

@MeowZheng
Copy link
Collaborator

According to the error TypeError: "img" must be a numpy array or a str or a pathlib.Path object

Please check the data type of input image

@alexgoft
Copy link
Author

alexgoft commented Jun 7, 2022

Thank you for the quick reply!

I passed a list of loaded images as specified in the documentation and I get the error above.
If I pass a NumPy array of crops (of slightly different shapes) I get the a different error:

  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/apis/inference.py", line 88, in inference_segmentor
    data = test_pipeline(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/compose.py", line 41, in __call__
    data = t(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/test_time_aug.py", line 120, in __call__
    data = self.transforms(_results)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/compose.py", line 41, in __call__
    data = t(data)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/transforms.py", line 285, in __call__
    self._resize_img(results)
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmseg/datasets/pipelines/transforms.py", line 241, in _resize_img
    img, scale_factor = mmcv.imrescale(
  File "/hdd/inspection_ai/venv/lib/python3.9/site-packages/mmcv/image/geometric.py", line 242, in imrescale
    h, w = img.shape[:2]
ValueError: not enough values to unpack (expected 2, got 1)

How can I run inference_segmentor properly on a batch of loaded crops? (essentially NumPy arrays). Passing a list/NumPy array of loaded images doesn't work.

@MeowZheng
Copy link
Collaborator

Could you please share with us which part of the document you referred?

@janyembo
Copy link

janyembo commented Jun 22, 2022

Hi, not sure if @alexgoft is referring to this

imgs (str/ndarray or list[str/ndarray]): Either image files or loaded

But I am facing the same issue of not being able to pass a List[ndarray] to inference_segmentor. Thanks!

@jinwonkim93
Copy link

Hi, I also encounter this issue. this is what i did for passing list.
#1849

@xiexinch
Copy link
Collaborator

Hi! Thank you for your quick response. I'm more curious about the reasoning behind a lack of class weighting though. Especially with the heavy imbalance of certain classes such as poles and trains in the Cityscapes dataset, it seems that class weighting would be necessary for the model to perform well as various CNN semantic segmentation architectures such as UNet or LinkNet utilize it in their experiments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants