albumentations
albumentations copied to clipboard
Keypoint flips are wrong
🐛 Bug
To Reproduce
Steps to reproduce the behavior:
- Take an image, say of 25 x 25 size, and assume that one of the keypoints is (24.5, 24.5)
- The logic in function keypoint_flip would do a calculation like (rows - 1) - x == -0.5
- later, this keypoint will get filtered out because it has a negative value
Expected behavior
I would have expected the value to be 0.5 and included in the keypoints list.
Environment
- Albumentations version (e.g., 0.1.8): 1.3.1
- Python version (e.g., 3.7):
- OS (e.g., Linux):
- How you installed albumentations (
conda
,pip
, source): - Any other relevant information:
Additional context
I had the same concern as well ~~and I feel like a similar issue occurs with ShiftScaleRotate as the center of the image is set as (cols - 1) * 0.5, (rows - 1) * 0.5
instead of just cols * 0.5, rows * 0.5
~~ (it seems that the shift has to happen for ShiftScaleRotate so that the rotation matrix that is retrieved from cv2 is accurate)
I've tried this method and it was totally correct:
def read_keypoints(keypoints_path):
df = pd.read_csv(keypoints_path, delimiter=',', names=["labels", "x", "y"])
# Convert 'x' and 'y' to integer if they are not NaN
df['x'] = pd.to_numeric(df['x'], errors='coerce').fillna(0).astype(int)
df['y'] = pd.to_numeric(df['y'], errors='coerce').fillna(0).astype(int)
return list(zip(df["x"], df["y"]))
def get_augmentation_pipeline():
return A.Compose([
A.HorizontalFlip(always_apply=True),
], keypoint_params=A.KeypointParams(format='xy', remove_invisible=True))
augmentation_pipeline = get_augmentation_pipeline()
transformed = augmentation_pipeline(image=image, keypoints=keypoints)
print(f"transformed keypoints: {transformed['keypoints']}")
@angle_2pi_range
def keypoint_hflip(keypoint: KeypointInternalType, rows: int, cols: int) -> KeypointInternalType:
"""Flip a keypoint horizontally around the y-axis.
Args:
keypoint: A keypoint `(x, y, angle, scale)`.
rows: Image height.
cols: Image width.
Returns:
A keypoint `(x, y, angle, scale)`.
"""
x, y, angle, scale = keypoint[:4]
angle = math.pi - angle
return (cols - 1) - x, y, angle, scale
for (24.5, 24.5) and image (25, 25) it will return (0.5, 24.5) as expected