-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error in keypoints when using large optical distortions #2285
Comments
I have found the origin of the issue but am sadly not able to think of a way to correct it... What I did to specifically achieve this is go into albumentations>augmentations>geomtric>functional.py>remap_keypoints
after "extensive" testing and math checking I simply decided to remove all the extras and just use the map_x and map_y for the reprojection:
Which resulted in the inverted distortion result of all the checkpoints. g.e.: When directly comparing that to the remap function that is actually applied to the image it is clear that cv2.remap must be doing something to invert the xy_map resulting in the inverting issue. |
Thanks, love such bug reports. Show deep domain knowledge of the reporter and effort he put into debug. Will look into it and fix. |
Hi, I can add something for A.ThinPlateSpline. Keypoints are also not correct when using A.ThinPlateSpline. OS: Linux via Windows WSL-2 Example: |
This issue was affecting all distortion: Optical, Elastic, ThinPlateSpline, Grid.Pushed a fix. Not ideal for points far from the center, but should work better than before. Two main issues:
If you have ideas on how to handle this better than now. I am all attention. |
Hi. OK, then there is no earlier version where this worked for points far from Center (some unoptimized version maybe)? Thank you very much. |
@RhysEvan created an improved version for the issue. Just merged it. |
@CometManAtGitHub Yes, most likely distortions always had issues with keypoints. And right now it finally looks correct. |
Hi, The output of the augmentations
for both
are y,x. This is not the case for rotation and affine e.g. Tested the main via pip install and also the release 2.0.1. It is detectable via: Also the augmentations are a lot slower than before, just to note. |
Thanks, will take a look. |
@CometManAtGitHub Updated. Fixed issues with x, y being switched (example with the cat) Now have two methods for dealing with keypoints. Both not ideal, but |
Thank you very much. It works ok and is fast. Some smaller offsets exist. But I also noticed a severe error, where landmarks disapeared. I created a replay for repetition, it might be used with the landmark extraction code from above for the cat. But it is 50 MB large, so here is the augmentation as code, the error should appear in 1 out of 10 cases. def apply_augmentations_image_keypoints(image, keypoints, width, height, with_replay=False):
"""Apply augmentations to an image and keypoints"""
interpolation = cv2.INTER_LANCZOS4
border_mode = cv2.BORDER_CONSTANT
value = (0, 0, 0)
fill_image = 0
rotate_limit = 30
remove_invisible = True # Remove keypoints which are not visible in the image due to cropping or rotation e.g.
keypoints_params = A.KeypointParams(format='xy', remove_invisible=remove_invisible) # , label_fields=['class_labels']
p = 1.0
# Simple augmentations
a_rotation = A.Rotate(limit=rotate_limit, interpolation=interpolation, border_mode=border_mode, fill=fill_image, p=p)
a_affine = A.Affine(scale=(0.9, 1.1), translate_percent=(0.1, 0.1), rotate=(-rotate_limit, rotate_limit), shear=(-10, 10), interpolation=interpolation, border_mode=border_mode, fill=fill_image, p=p)
a_padifneeded = A.PadIfNeeded(min_height=height, min_width=width, border_mode=border_mode, p=p)
a_centercrop = A.CenterCrop(height=height, width=width, p=1.0)
# Complex augmentations
alpha = 1
sigma = 50
a_elastic = A.ElasticTransform(alpha=alpha, sigma=sigma, interpolation=interpolation, p=p)
num_steps = 2 # 1 ... 5
distort_limit = 0.3 # 0.1 ... 0.5
a_griddistortion = A.GridDistortion(num_steps=num_steps, distort_limit=distort_limit, normalized = False, interpolation=interpolation, p=p)
distort_limit = [0.0, 0.95]
mode = "fisheye"
a_opticaldistortion = A.OpticalDistortion(distort_limit=distort_limit, mode=mode, interpolation=interpolation, p=p)
scale_range = [0.2, 0.4]
num_control_points = 2
a_thinplatespline = A.ThinPlateSpline(scale_range=scale_range, num_control_points=num_control_points, interpolation=interpolation, p=p)
# Sometimes we want repeatable augmentations
Composer = A.Compose
if with_replay:
Composer = A.ReplayCompose
# Define augmentation pipeline
augmentations = Composer([
a_rotation, # correct
a_affine, # correct
a_elastic, # =============> ERRORS with albumentations < 2.0.4 <=============
a_griddistortion, # =============> ERRORS with albumentations < 2.0.4 <=============
a_opticaldistortion, # =============> ERRORS with albumentations < 2.0.4 <=============
a_thinplatespline, # =============> ERRORS with albumentations < 2.0.4 <=============
# a_padifneeded,
# a_centercrop
], keypoint_params=keypoints_params) As you already stated it will not work for extreme cases like when duplication of landmarks appear. Update: I can recreate the problem with vanished keypoints by only applying griddistortion. |
Describe the bug
When applying large deformations using opticaldistortion the keypoints are not transformed correctly.
To Reproduce
OS: Windows
Python version 3.11
Albumentations V2.0.0
Steps to reproduce the behavior:
import cv2
import numpy as np
import albumentations as A
from albumentations.core.composition import KeypointParams
import matplotlib.pyplot as plt
Expected behavior
The keypoints should be aligned with the internal checkers.
Actual behavior
The transformation between the image and the keypoints are not aligned
Screenshots
The text was updated successfully, but these errors were encountered: