albumentations-team / albumentations

Fast and flexible image augmentation library. Paper about the library: https://www.mdpi.com/2078-2489/11/2/125
https://albumentations.ai
MIT License
13.79k stars 1.61k forks source link

all the input arrays must have same number of dimensions #354

Closed hazardwayne closed 4 years ago

hazardwayne commented 4 years ago

🐛 Bug

To Reproduce

Steps to reproduce the behavior:

when i use the notebook from https://github.com/qubvel/segmentation_models/blob/master/examples/multiclass%20segmentation%20(camvid).ipynb, with Resize transform turn on, raises the above error.

Expected behavior

Environment

Additional context

Dipet commented 4 years ago

I can not reproduce this problem. Can you give traceback for this error?

hazardwayne commented 4 years ago

ValueError Traceback (most recent call last)

in 2 dataset = Dataset(root_dir="../data/train_images", ann_file="train.csv", dataframe=train_df, num_classes=4, augmentation=get_training_augmentation()) 3 ----> 4 image, mask = dataset[0] # get some sample 5 visualize(image=image, background=mask[:,:,0], class1=mask[:,:,1], class2=mask[:,:,2], class3=mask[:,:,3], class4=mask[:,:,4]) in __getitem__(self, i) 85 # apply augmentations 86 if self.augmentation: ---> 87 sample = self.augmentation(image=image, mask=mask) 88 image, mask = sample['image'], sample['mask'] 89 /mnt/wenhongdiao/.pylib/3/albumentations/core/composition.py in __call__(self, force_apply, **data) 156 p.preprocess(data) 157 --> 158 data = t(force_apply=force_apply, **data) 159 160 if dual_start_end is not None and idx == dual_start_end[1]: /mnt/wenhongdiao/.pylib/3/albumentations/core/transforms_interface.py in __call__(self, force_apply, **kwargs) 63 target_function = self._get_target_function(key) 64 target_dependencies = {k: kwargs[k] for k in self.target_dependence.get(key, [])} ---> 65 res[key] = target_function(arg, **dict(params, **target_dependencies)) 66 else: 67 res[key] = None /mnt/wenhongdiao/.pylib/3/albumentations/augmentations/transforms.py in apply_to_mask(self, img, angle, **params) 414 415 def apply_to_mask(self, img, angle=0, **params): --> 416 return F.rotate(img, angle, cv2.INTER_NEAREST, self.border_mode, self.mask_value) 417 418 def get_params(self): /mnt/wenhongdiao/.pylib/3/albumentations/augmentations/functional.py in wrapped_function(img, *args, **kwargs) 56 def wrapped_function(img, *args, **kwargs): 57 shape = img.shape ---> 58 result = func(img, *args, **kwargs) 59 if len(shape) == 3 and shape[-1] == 1 and len(result.shape) == 2: 60 result = np.expand_dims(result, axis=-1) /mnt/wenhongdiao/.pylib/3/albumentations/augmentations/functional.py in rotate(img, angle, interpolation, border_mode, value) 172 warp_fn = _maybe_process_in_chunks(cv2.warpAffine, M=matrix, dsize=(width, height), flags=interpolation, 173 borderMode=border_mode, borderValue=value) --> 174 return warp_fn(img) 175 176 /mnt/wenhongdiao/.pylib/3/albumentations/augmentations/functional.py in __process_fn(img) 157 chunk = process_fn(chunk, **kwargs) 158 chunks.append(chunk) --> 159 img = np.concatenate(chunks, axis=2) 160 else: 161 img = process_fn(img, **kwargs) ValueError: all the input arrays must have same number of dimensions
albu commented 4 years ago

@BloodAxe ?

Dipet commented 4 years ago

@BloodAxe I catch this error with 5 channel images

hazardwayne commented 4 years ago

In my situation, the target mask has 5 channels too.

nsfabina commented 4 years ago

Here's a minimal reproducible example:

import albumentations
import bumpy as np

im = np.ones((128, 128, 3))
mask = np.ones((128, 128, 5))
data = {'image': im, 'mask': mask}

apply_augmentations = albumentations.Compose([
    albumentations.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.05, rotate_limit=45, p=1),
])
augmented = apply_augmentations(**data)

With traceback:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-507-5a7c15e6062f> in <module>
      7     albumentations.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.05, rotate_limit=45, p=1),
      8 ])
----> 9 augmented = apply_augmentations(**data)

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/core/composition.py in __call__(self, force_apply, **data)
    156                     p.preprocess(data)
    157 
--> 158             data = t(force_apply=force_apply, **data)
    159 
    160             if dual_start_end is not None and idx == dual_start_end[1]:

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/core/transforms_interface.py in __call__(self, force_apply, **kwargs)
     63                     target_function = self._get_target_function(key)
     64                     target_dependencies = {k: kwargs[k] for k in self.target_dependence.get(key, [])}
---> 65                     res[key] = target_function(arg, **dict(params, **target_dependencies))
     66                 else:
     67                     res[key] = None

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/augmentations/transforms.py in apply_to_mask(self, img, angle, scale, dx, dy, **params)
    515 
    516     def apply_to_mask(self, img, angle=0, scale=0, dx=0, dy=0, **params):
--> 517         return F.shift_scale_rotate(img, angle, scale, dx, dy, cv2.INTER_NEAREST, self.border_mode, self.mask_value)
    518 
    519     def apply_to_keypoint(self, keypoint, angle=0, scale=0, dx=0, dy=0, rows=0, cols=0, interpolation=cv2.INTER_LINEAR,

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/augmentations/functional.py in wrapped_function(img, *args, **kwargs)
     56     def wrapped_function(img, *args, **kwargs):
     57         shape = img.shape
---> 58         result = func(img, *args, **kwargs)
     59         if len(shape) == 3 and shape[-1] == 1 and len(result.shape) == 2:
     60             result = np.expand_dims(result, axis=-1)

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/augmentations/functional.py in shift_scale_rotate(img, angle, scale, dx, dy, interpolation, border_mode, value)
    199     warp_affine_fn = _maybe_process_in_chunks(cv2.warpAffine, M=matrix, dsize=(width, height), flags=interpolation,
    200                                               borderMode=border_mode, borderValue=value)
--> 201     return warp_affine_fn(img)
    202 
    203 

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/augmentations/functional.py in __process_fn(img)
    157                 chunk = process_fn(chunk, **kwargs)
    158                 chunks.append(chunk)
--> 159             img = np.concatenate(chunks, axis=2)
    160         else:
    161             img = process_fn(img, **kwargs)

ValueError: all the input arrays must have same number of dimensions
nsfabina commented 4 years ago

This'll affect all the augmentations that use _maybe_process_in_chunks:

nsfabina commented 4 years ago

I'm pretty sure the fix here is:

Currently:

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/augmentations/functional.py in __process_fn(img)
    157                 chunk = process_fn(chunk, **kwargs)
    158                 chunks.append(chunk)
--> 159             img = np.concatenate(chunks, axis=2)
    160         else:
    161             img = process_fn(img, **kwargs)

Becomes:

~/miniconda3/envs/asu/lib/python3.7/site-packages/albumentations/augmentations/functional.py in __process_fn(img)
    157                 chunk = process_fn(chunk, **kwargs)
    158                 chunks.append(chunk)
--> 159             img = np.dstack(chunks)
    160         else:
    161             img = process_fn(img, **kwargs)
Dipet commented 4 years ago

Fixed #364