mjkvaak / ImageDataAugmentor

Custom image data generator for TF Keras that supports the modern augmentation module albumentations
Other
86 stars 27 forks source link

generator does not work with float16 #18

Closed IkhlasAhmad1998 closed 3 years ago

IkhlasAhmad1998 commented 3 years ago

hi, i am loading my images as float16 due to memory limitations and creating the generators like this:

b = 16

BACKBONE = 'resnet18'

preprocess_input = sm.get_preprocessing(BACKBONE)

train_datagen = ImageDataAugmentor(augment=AUGMENTATIONS, input_augment_mode='image', label_augment_mode="mask", preprocess_input=preprocess_input)
train_generator = train_datagen.flow(train_images_s, train_masks_s, batch_size=b, dtype='float16')

val_datagen = ImageDataAugmentor(input_augment_mode='image', label_augment_mode="mask", preprocess_input=preprocess_input)
val_generator = val_datagen.flow(val_images_s, val_masks_s, batch_size=b, dtype='float16')

test_datagen = ImageDataAugmentor(input_augment_mode='image', label_augment_mode="mask", preprocess_input=preprocess_input)
test_generator = test_datagen.flow(test_images_s, test_masks_s, batch_size=b, dtype='float16')

but when try to get output like this: batch ,image, mask = train_generator.next()

it throws an error:

error                                     Traceback (most recent call last)

<ipython-input-53-09b5c38198ee> in <module>()
----> 1 batch ,image, mask = train_generator.next()

11 frames

/usr/local/lib/python3.7/dist-packages/albumentations/augmentations/functional.py in __process_fn(img)
    187             img = np.dstack(chunks)
    188         else:
--> 189             img = process_fn(img, **kwargs)
    190         return img
    191 

error: OpenCV(4.5.3) :-1: error: (-5:Bad argument) in function 'warpAffine'
> Overload resolution failed:
>  - src data type = 23 is not supported
>  - Expected Ptr<cv::UMat> for argument 'src'

how can i fix it? thanks

mjkvaak commented 3 years ago

This is due to the fact that some of your augmentations do not support 16bit floats. You can find out the dtypes supported by albumentations in here. For example, Blur does not support float16 (see documentation -> Image types):

This works

dummy_img = np.random.uniform(0,1, (256,256,3)).astype('float16')
AUGMENTATIONS = albumentations.Compose([
    albumentations.HorizontalFlip(p=1.),
])
AUGMENTATIONS(image=dummy_img)

but this fails

dummy_img = np.random.uniform(0,1, (256,256,3)).astype('float16')
AUGMENTATIONS = albumentations.Compose([
    albumentations.Blur(p=1.)
])
AUGMENTATIONS(image=dummy_img)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_14782/578408663.py in <module>
      9     albumentations.Blur(p=1.)
     10 ])
---> 11 AUGMENTATIONS(image=dummy_img)

~/anaconda3/envs/ida/lib/python3.7/site-packages/albumentations/core/composition.py in __call__(self, force_apply, *args, **data)
    180                     p.preprocess(data)
    181 
--> 182             data = t(force_apply=force_apply, **data)
    183 
    184             if dual_start_end is not None and idx == dual_start_end[1]:

~/anaconda3/envs/ida/lib/python3.7/site-packages/albumentations/core/transforms_interface.py in __call__(self, force_apply, *args, **kwargs)
     87                     )
     88                 kwargs[self.save_key][id(self)] = deepcopy(params)
---> 89             return self.apply_with_params(params, **kwargs)
     90 
     91         return kwargs

~/anaconda3/envs/ida/lib/python3.7/site-packages/albumentations/core/transforms_interface.py in apply_with_params(self, params, force_apply, **kwargs)
    100                 target_function = self._get_target_function(key)
    101                 target_dependencies = {k: kwargs[k] for k in self.target_dependence.get(key, [])}
--> 102                 res[key] = target_function(arg, **dict(params, **target_dependencies))
    103             else:
    104                 res[key] = None

~/anaconda3/envs/ida/lib/python3.7/site-packages/albumentations/augmentations/transforms.py in apply(self, image, ksize, **params)
   2511 
   2512     def apply(self, image, ksize=3, **params):
-> 2513         return F.blur(image, ksize)
   2514 
   2515     def get_params(self):

~/anaconda3/envs/ida/lib/python3.7/site-packages/albumentations/augmentations/functional.py in wrapped_function(img, *args, **kwargs)
     52     def wrapped_function(img, *args, **kwargs):
     53         shape = img.shape
---> 54         result = func(img, *args, **kwargs)
     55         result = result.reshape(shape)
     56         return result

~/anaconda3/envs/ida/lib/python3.7/site-packages/albumentations/augmentations/functional.py in blur(img, ksize)
    725 def blur(img, ksize):
    726     blur_fn = _maybe_process_in_chunks(cv2.blur, ksize=(ksize, ksize))
--> 727     return blur_fn(img)
    728 
    729 

~/anaconda3/envs/ida/lib/python3.7/site-packages/albumentations/augmentations/functional.py in __process_fn(img)
    186             img = np.dstack(chunks)
    187         else:
--> 188             img = process_fn(img, **kwargs)
    189         return img
    190 

TypeError: Expected Ptr<cv::UMat> for argument 'src'
mjkvaak commented 3 years ago

Nevertheless, you can fix the problem by using albumentations.Lambda-transforms:

def to_float32(x, **kwargs):
    return x.astype('float32')

def to_float16(x, **kwargs):
    return x.astype('float16')

dummy_img = np.random.uniform(0,1, (256,256,3)).astype('float16')
AUGMENTATIONS = albumentations.Compose([
    albumentations.Lambda(image=to_float32, p=1.),
    albumentations.Blur(p=1.),
    albumentations.Lambda(image=to_float16, p=1.),

])
AUGMENTATIONS(image=dummy_img)

I will close the issue.