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
14.19k stars 1.65k forks source link

Segmentation masks shift after A.Resize #1324

Open kakukakujirori opened 2 years ago

kakukakujirori commented 2 years ago

šŸ› Bug

I noticed A.Resize shifts the alignment of an RGB image and its corresponding segmentation masks, and especially masks are shifted in the right direction.

The same phenomenon also happens if we use A.RandomResizedCrop.

To Reproduce

import requests
from io import BytesIO
from PIL import Image
import numpy as np
import cv2
import matplotlib.pyplot as plt
import albumentations as A

fig, ax = plt.subplots(1, 2, figsize=(10, 5))

# original image
response = requests.get("https://miro.medium.com/max/1200/1*lHMua9ruClZwHR8O0fyO7A.jpeg")
img = np.array(Image.open(BytesIO(response.content)))
img, mask = np.split(img, 2, axis=1)
ret = cv2.addWeighted(img, 0.5, mask, 0.5, 0)
ax[0].imshow(ret, aspect='auto')

# resized image
aug = A.Resize(256, 256, always_apply=True)
transformed = aug(image=img, mask=mask)
img_aug, mask_aug = transformed["image"], transformed["mask"]
ret_aug = cv2.addWeighted(img_aug, 0.5, mask_aug, 0.5, 0)
ax[1].imshow(ret_aug, aspect='auto')

plt.show()

Result: you can see the man's right shoulder is not aligned with the red mask after resize. (Before Resize <===> After Resize) output

Expected behavior

This phenomenon doesn't occur if you use cv2.resize or torchvision.transforms.Resize.

import requests
from io import BytesIO
from PIL import Image
import numpy as np
import cv2
import matplotlib.pyplot as plt
import albumentations as A

fig, ax = plt.subplots(1, 2, figsize=(10, 5))

# original image
response = requests.get("https://miro.medium.com/max/1200/1*lHMua9ruClZwHR8O0fyO7A.jpeg")
img = np.array(Image.open(BytesIO(response.content)))
img, mask = np.split(img, 2, axis=1)
ret = cv2.addWeighted(img, 0.5, mask, 0.5, 0)
ax[0].imshow(ret, aspect='auto')

# resized image
img_aug = cv2.resize(img, (256, 256))
mask_aug = cv2.resize(mask, (256, 256))
ret_aug = cv2.addWeighted(img_aug, 0.5, mask_aug, 0.5, 0)
ax[1].imshow(ret_aug, aspect='auto')

plt.show()

Result: (Before Resize <===> After Resize) output2

Environment

Andredance commented 2 years ago

I think it is related to #850.