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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Full images datamanager] fix image indexing with cv.undistort and implement eval indices logic #2683

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

maturk
Copy link
Collaborator

@maturk maturk commented Dec 16, 2023

Two things:

1) fix new undistorted image shape not being the same as input

from my understanding in newK, roi = cv2.getOptimalNewCameraMatrix(K, distortion_params, (image.shape[1], image.shape[0]), 0) the roi that is returned is in pixel notations (px_start, py_start, px_end, py_end)

When slicing an image we should instead do image[y : y + h + 1, x : x + w + 1] to preserve the same shape as the input image. Otherwise we crop the last pixel and output_image.shape != input_image.shape :D

2) add eval indices logic from config

There are a few nice eval options in the config that haven't been implemented. I implemented an easy version for eval_num_images_to_sample_from and eval_image_indices which I think are the most important ones for evaluating.

@maturk maturk changed the title [Full images datamanager] fix image indexing with cv.undistort [Full images datamanager] fix image indexing with cv.undistort and implement eval indices logic Dec 16, 2023
@@ -150,19 +164,19 @@ def cache_images(self, cache_images_option):
image = cv2.undistort(image, K, distortion_params, None, newK) # type: ignore
# crop the image and update the intrinsics accordingly
x, y, w, h = roi
image = image[y : y + h, x : x + w]
image = image[y : y + h + 1, x : x + w + 1]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should preserve 1) input.shape == output.shape

@maturk
Copy link
Collaborator Author

maturk commented Dec 26, 2023

also added option for mipnerf360 style evaluation in colmap dataparser to hold out every n'th image in train set for eval dataset. Useful for comparing with inria eval scripts

@maturk
Copy link
Collaborator Author

maturk commented Jan 3, 2024

Reverted sampling strategies in colmap dataparser in favour of the new PR #2709 which also implements them. This PR fixes 1) the output image size bug after cv.undistort and 2) implements the logic for "eval_image_indices" and "eval_num_images_to_sample_from" in the datamanager config.

@kerrj
Copy link
Collaborator

kerrj commented Jan 8, 2024

How does this PR interact with #2726 ?

@liorfritz
Copy link
Contributor

isn't it OK that after the undistortion the shape of the image changes?
Maybe the fact that in Mip-NeRF 360 the images are already undistorted, and the second undistortion caused a loss of pixel (prior to PR #2726), lead to this change?

@jb-ye
Copy link
Collaborator

jb-ye commented Jan 8, 2024

@maturk For the first issue: do you have sources indicating the roi is in (left, upper, right, lower) convention? I think it is in x, y, w, h convention. If you search code on github for sample codes of using cv2.getOptimalNewCameraMatrix(), the current implementation is correct.

@f-dy
Copy link
Contributor

f-dy commented Jan 9, 2024

The fix should be done upstream: w and h returned by the latest version of icvGetRectangles are off by 1 pixel, see opencv/opencv#24831

@maturk
Copy link
Collaborator Author

maturk commented Jan 9, 2024

@f-dy okay wow this is actually pretty crazy XD Never would I have thought that I would find a bug in OpenCV! Thank you for making the issue and even tracking down the problem in the source code.

@f-dy
Copy link
Contributor

f-dy commented Jan 9, 2024

I would recommend adding a unit test to test_datamanager.py, so that we're sure to get the thing right in the end.

@f-dy
Copy link
Contributor

f-dy commented Jan 9, 2024

And btw we should probably not use cv.undistort, which uses bilinear interpolation, and write our own function that calls cv2.remap with INTER_CUBIC instead. bilinear interpolation creates uneven blur in the image, especially for small distortion amounts, i.e with a small k1 you would see rings of blur in the undistorted images. I'll add some code that demonstrates that

@kerrj
Copy link
Collaborator

kerrj commented Jan 9, 2024

So with opencv 4.8+ this is no longer an issue?

@liorfritz
Copy link
Contributor

Still an issue, even with 4.9.
Hopefully will be patched in the future, following the issue that @f-dy opened.

@maturk
Copy link
Collaborator Author

maturk commented Jan 10, 2024

Any suggestions what we should do with this issue with the cropped pixel?

@jb-ye
Copy link
Collaborator

jb-ye commented Jan 10, 2024

@maturk Let's wait opencv's team to fix this bug, I believe they will fix it very soon. Once they fix the issue, we can bump up opencv version dependency again.

@f-dy
Copy link
Contributor

f-dy commented Jan 11, 2024

Any suggestions what we should do with this issue with the cropped pixel?

gate the fix you did with if 4.8<=opencv_version<4.10, since the issue is marked for OpenCV 4.10, and add a unit test, so that we can adjust the gate if they don't fix it in 4.10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants