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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

RandomSunFlare dump #1072

Closed
Tim5Tang opened this issue Dec 1, 2021 · 13 comments 路 Fixed by #1333
Closed

RandomSunFlare dump #1072

Tim5Tang opened this issue Dec 1, 2021 · 13 comments 路 Fixed by #1333
Labels
bug Something isn't working Need more info

Comments

@Tim5Tang
Copy link

Tim5Tang commented Dec 1, 2021

馃悰 Bug

To Reproduce

add function
A.RandomSunFlare(p=0.2)

Steps to reproduce the behavior:

/Pytorch/lib/python3.6/site-packages/albumentations/augmentations/functional.py", line 863, in add_sun_flare
cv2.circle(overlay, (x, y), rad3, (r_color, g_color, b_color), -1)
cv2.error: OpenCV(4.5.4) 馃憥 error: (-5:Bad argument) in function 'circle'

Overload resolution failed:

  • Can't parse 'center'. Sequence item with index 1 has a wrong type
  • Can't parse 'center'. Sequence item with index 1 has a wrong type

Expected behavior

Environment

  • Albumentations version (e.g., 0.1.8): albumentations 1.1.0
  • Python version (e.g., 3.6): 3.6
  • OS (e.g., Linux): linux
  • How you installed albumentations (conda, pip, source): pip
  • Any other relevant information:

Additional context

@bilal-sher-nyu
Copy link

bilal-sher-nyu commented Dec 6, 2021

Having a similar issue with OpenCV.

Error Produced is:

Traceback (most recent call last):
  File "c:/Users/bilal/NYU Courses/Fall 2021/02 - MSc Thesis Option/01 - Research/Yo Hou Dataset Testing/dataset.py", line 104, in <module>
    image, mask = next(iter(train_ds))
  File "c:/Users/bilal/NYU Courses/Fall 2021/02 - MSc Thesis Option/01 - Research/Yo Hou Dataset Testing/dataset.py", line 66, in __getitem__
    augmentations = self.transform(image=image_, mask=masks_)
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\core\composition.py", line 210, in __call__
    data = t(force_apply=force_apply, **data)
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\core\transforms_interface.py", line 97, in __call__
    return self.apply_with_params(params, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\core\transforms_interface.py", line 112, in apply_with_params
    res[key] = target_function(arg, **dict(params, **target_dependencies))
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\core\transforms_interface.py", line 241, in apply_to_mask
    return self.apply(img, **{k: cv2.INTER_NEAREST if k == "interpolation" else v for k, v in params.items()})
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\augmentations\geometric\resize.py", line 177, in apply
    return F.resize(img, height=self.height, width=self.width, interpolation=interpolation)
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\augmentations\functional.py", line 70, 
in wrapped_function
    result = func(img, *args, **kwargs)
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\augmentations\geometric\functional.py", line 277, in resize
    return resize_fn(img)
  File "C:\ProgramData\Anaconda3\lib\site-packages\albumentations\augmentations\functional.py", line 185, in __process_fn
    chunk = process_fn(chunk, **kwargs)
cv2.error: OpenCV(4.5.4) :-1: error: (-5:Bad argument) in function 'resize'
> Overload resolution failed:
>  - src data type = 0 is not supported
>  - Expected Ptr<cv::UMat> for argument 'src'`

Code is:

import torchvision.transforms as T
import os
from PIL import Image
from torch.utils.data import Dataset
import numpy as np
from pycocotools.coco import COCO
import torch
import cv2
import albumentations as A
from albumentations.pytorch import ToTensorV2

class YoHouDataset(Dataset):
    def __init__(self, image_dir, transform = None):
        self.image_dir = image_dir
        self.transform = transform
        self.images = os.listdir(image_dir)
        self.path_annotations = os.path.join(os.getcwd(),"Flug1_105Media_coco.json")
        # self.f = open(self.path_annotations, 'r')
        # self.db = json.load(self.f)
        self.coco=COCO(self.path_annotations)
        
    def __len__(self):
        return len(self.images)
    
    def __getitem__(self, index):
        img_path = os.path.join(self.image_dir, self.images[index])
        image_id = index
        image_ = np.load(img_path,allow_pickle=True)[:,:,3]
        cv2.imshow('test_image',image_)
        cv2.waitKey(0)   #wait for a keyboard input
        cv2.destroyAllWindows()
        # image_ = torch.as_tensor(image_)
        image_height = image_.shape[0]
        image_width = image_.shape[1]
        
        #This will create the mask 
        mask_ = np.zeros((image_height, image_width))
        category = 0
        annIds = self.coco.getAnnIds(imgIds=image_id,catIds=category)
        anns = self.coco.loadAnns(annIds)
        for i in range(len(anns)):
            mask_ += (self.coco.annToMask(anns[i])*(i+1))
            mask_ += 1
        mask_ -= np.unique(mask_)[0]
        obj_ids = np.unique(mask_)
        obj_ids = obj_ids[1:]
        masks_ = mask_ == obj_ids[:, None, None]
        print(type(masks_))
        # masks = torch.as_tensor(masks, dtype=torch.uint8)
        print(f"Loaded Picture {index}")
        
        if self.transform is not None:
            augmentations = self.transform(image=image_, mask=masks_)
            image = augmentations['image']
            masks = augmentations['mask']
            # image, masks = self.transform(image, masks)
        
        return image, masks
    
def get_transform(train):
    transforms = []
    transforms.append(T.ToTensor())
    if train:
        transforms.append(T.RandomHorizontalFlip(0.5))
    return T.Compose(transforms)



if __name__ == "__main__":
    IMAGE_HEIGHT = 2400 #Originally 2400
    IMAGE_WIDTH = 3200 #Originally 3200
    TRAIN_IMG_DIR = "images/Flug1_105Media/"
    train_transforms = A.Compose(
        [
            # A.Resize(height=IMAGE_HEIGHT, width=IMAGE_WIDTH),
            A.Rotate(limit=35, p=1.0),
            A.HorizontalFlip(p=0.5),
            A.VerticalFlip(p=0.1),
            A.Normalize(
                mean = [0.0, 0.0, 0.0],
                std = [1.0, 1.0, 1.0],
                max_pixel_value = 255.0,
            ),
            ToTensorV2(),
        ],
    )
    train_ds = YoHouDataset(
        image_dir=TRAIN_IMG_DIR,
        transform=train_transforms,#transform=get_transform(train=True),
    )
    image, mask = next(iter(train_ds))

@bilal-sher-nyu
Copy link

@Tim5Tang https://www.youtube.com/watch?v=NlhUpZKmzJ4&ab_channel=crazzylearners

Although majority of the video is in Hindi, the basic gist of it is that if you input a wrong datatype into a function, it will result in the OpenCV giving an error.

In the video he starts off by inputting an image, then he instead inputs a string and he gets the same error to spit out. He then inputs the image, but changes a different variable to produce a different error.

The error we're seeing is an OpenCV error due to inputting the wrong type.

@Tim5Tang
Copy link
Author

Tim5Tang commented Dec 7, 2021

@bilal-sher-nyu ok, thanks, i will test it, may be i have input the wrong type.

@vmmm123
Copy link

vmmm123 commented Aug 30, 2022

the problem happens to me..how do u fix it? I am pretty sure that the input type is right

@Dipet
Copy link
Collaborator

Dipet commented Aug 30, 2022

Does the problem exist on the in latest version of the library?
Try call np.ascontiguousarray for image and mask before provide them into transforms.

@vmmm123
Copy link

vmmm123 commented Sep 1, 2022

thanks, but it still doesnot work...

@Dipet
Copy link
Collaborator

Dipet commented Sep 2, 2022

Please, provide minimal reproducible example.

@hoel-bagard
Copy link
Contributor

hoel-bagard commented Sep 15, 2022

@Dipet I have the same the same issue as the first post:

  File "/home/hoel/.local/lib/python3.10/site-packages/albumentations/augmentations/functional.py", line 979, in add_sun_flare
    cv2.circle(overlay, (x, y), rad3, (r_color, g_color, b_color), -1)
cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'circle'
> Overload resolution failed:
>  - Can't parse 'center'. Sequence item with index 1 has a wrong type
>  - Can't parse 'center'. Sequence item with index 1 has a wrong type

However I cannot make a reproducible example. During my trainings, the error appeared seemingly randomly after 40 and 28 epochs. I thought it might be a bad combination of augmentations, so I put all the probabilities at one in an attempt to reproduce it, but the error still does not appear straight away.
From the error message, it's as if the x and y extremely rarely, randomly, have a wrong type like a float when creating the circle arguments (here I assume). But since the coordinates are explicitly casted to ints, I don't see how this is happening.

Environment

  • Albumentations version: 1.2.1
  • Python version: 3.10
  • OS: Linux
  • How you installed albumentations: pip

@vmmm123
Copy link

vmmm123 commented Sep 15, 2022

@Dipet I have the same the same issue as the first post:

  File "/home/hoel/.local/lib/python3.10/site-packages/albumentations/augmentations/functional.py", line 979, in add_sun_flare
    cv2.circle(overlay, (x, y), rad3, (r_color, g_color, b_color), -1)
cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'circle'
> Overload resolution failed:
>  - Can't parse 'center'. Sequence item with index 1 has a wrong type
>  - Can't parse 'center'. Sequence item with index 1 has a wrong type

However I cannot make a reproducible example. During my trainings, the error appeared seemingly randomly after 40 and 28 epochs. I thought it might be a bad combination of augmentations, so I put all the probabilities at one in an attempt to reproduce it, but the error still does not appear straight away. From the error message, it's as if the x and y extremely rarely, randomly, have a wrong type like a float when creating the circle arguments (here I assume). But since the coordinates are explicitly casted to ints, I don't see how this is happening.

Environment

  • Albumentations version: 1.2.1
  • Python version: 3.10
  • OS: Linux
  • How you installed albumentations: pip

So was I! The error occurs at random in the training stage.

@Dipet Dipet added bug Something isn't working Need more info labels Sep 15, 2022
@jasonrock-a3
Copy link
Contributor

@Dipet I wrote a script to just keep making new images until it broke printing out the center, and can say with some certainty that the problem has to do with python ints not being 64 bit, but opencv being implemented in cpp using 64 bit ints.

Full code here (repro for me took ~24 hours using this single threaded approach).

from PIL import Image
import albumentations as A
import numpy as np

class FakeDataset:
    def __init__(self):
        self.fake_len = 1000
        self.aug = A.RandomSunFlare(p=1.0)


    def __len__(self):
        return self.fake_len


    def __getitem__(self, idx):
        image = np.array(Image.new('RGB', (311,255)))
        return self.aug(image=image)


if __name__ == "__main__":
    import pdb 
    dataset = FakeDataset()

    while True:
        val = dataset[0]

Patch to add debug prints

diff --git a/albumentations/augmentations/functional.py b/albumentations/augmentations/functional.py
index 700bb79..ff74ac0 100644
--- a/albumentations/augmentations/functional.py
+++ b/albumentations/augmentations/functional.py
@@ -698,6 +698,7 @@ def add_sun_flare(img, flare_center_x, flare_center_y, src_radius, src_color, ci
     output = img.copy()
 
     for (alpha, (x, y), rad3, (r_color, g_color, b_color)) in circles:
+        print(f"center: ({x},{y})")
         cv2.circle(overlay, (x, y), rad3, (r_color, g_color, b_color), -1) 
 
         cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, output)

Output (clipped obviously)

...
center: (180,184)
center: (90,-8)
center: (210,248)
center: (180,184)
center: (100,137)
center: (250,-199)
center: (70,204)
center: (280,-267)
center: (240,-177)
center: (100,137)
center: (60,227)
center: (40,-1444370434)
center: (0,-2194692778)
Traceback (most recent call last):
  File "test_dl.py", line 25, in <module>
    val = dataset[0]
  File "test_dl.py", line 17, in __getitem__
    return self.aug(image=image)
  File "/home/jason.rock/albumentations/albumentations/core/transforms_interface.py", line 118, in __call__
    return self.apply_with_params(params, **kwargs)
  File "/home/jason.rock/albumentations/albumentations/core/transforms_interface.py", line 131, in apply_with_params
    res[key] = target_function(arg, **dict(params, **target_dependencies))
  File "/home/jason.rock/albumentations/albumentations/augmentations/transforms.py", line 656, in apply
    return F.add_sun_flare(
  File "/home/jason.rock/albumentations/albumentations/augmentations/utils.py", line 107, in wrapped_function
    result = func(img, *args, **kwargs)
  File "/home/jason.rock/albumentations/albumentations/augmentations/functional.py", line 702, in add_sun_flare
    cv2.circle(overlay, (x, y), rad3, (r_color, g_color, b_color), -1)
cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'circle'
> Overload resolution failed:
>  - Can't parse 'center'. Sequence item with index 1 has a wrong type
>  - Can't parse 'center'. Sequence item with index 1 has a wrong type

@jasonrock-a3
Copy link
Contributor

jasonrock-a3 commented Oct 26, 2022

The root cause is https://github.com/albumentations-team/albumentations/blob/master/albumentations/augmentations/transforms.py#L689

math.tan(pi/2-epsilon) --> inf

I'm not sure I understand the goal of the tan here well enough to offer a fix at the moment, but I'll see if I can put a PR together.

@jasonrock-a3
Copy link
Contributor

If I understand this correctly, basically when the angle is pi/2 or 3pi/2 the sun is directly above or below, so the sampling of centers along the x direction doesn't work. My trivial fix to clip will at least remove the crashes but will leave behind a "data" bug at samples near pi/2 and 3pi/2. I believe there might already be a bit of a data bug here because the range of tan is covered in pi, not 2pi, so I believe the current approach might be difficult to parameterize since it is double sampling the range.

A more complete fix would be to generate points from the the line defined by centroid and the angle and then sample along that line both in the positive and negative direction.

@jasonrock-a3
Copy link
Contributor

Also if anyone stumbles on this before the fix is put in, you can workaround this issue by limiting the range of the input to tan to (.25, .75) avoid the integer overflow (pick whatever arbitrary limit you want, but keep in mind tan((.25 + epsilon)*2*pi)) = O(1/epsilon))

epsilon = .001
A.RandomSunFlare(..., angle_lower=.25 + epsilon, angle_upper=.75 - epsilon, ...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Need more info
Projects
None yet
6 participants