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

Add OpenCV as an option for rotation #6089

Merged
merged 6 commits into from
Apr 22, 2022
Merged

Add OpenCV as an option for rotation #6089

merged 6 commits into from
Apr 22, 2022

Conversation

ayshih
Copy link
Member

@ayshih ayshih commented Apr 19, 2022

To do:

  • Figure out some sane way to link to the documentation for cv2.warpAffine()
  • Fix the bug in pytest-mpl for generating the HTML summary when an image comparison fails due to a mismatch in image dimensions Bug is present in pytest-mpl 0.14.0, but is not present in the dev branch.

@ayshih ayshih added map Affects the map submodule image Affects the image submodule No Backport A PR that isn't to be backported to any release branch. (To be used as a flag to other maintainers) labels Apr 19, 2022
sunpy/image/transform.py Outdated Show resolved Hide resolved
sunpy/image/transform.py Outdated Show resolved Hide resolved
@cbard
Copy link
Contributor

cbard commented Apr 19, 2022

Hey @ayshih ! Thanks for digging out my old PR and incorporating it into your rotate redesign!

@ayshih
Copy link
Member Author

ayshih commented Apr 20, 2022

Rats, my implementation isn't working correctly on non-square pixels... Stay tuned

@ayshih
Copy link
Member Author

ayshih commented Apr 20, 2022

To be clear, I mean non-square pixels that are not aligned with the coordinate axes, that is a PCij matrix that is not a pure rotation (see #5784/#5803)

setup.cfg Show resolved Hide resolved
@ayshih
Copy link
Member Author

ayshih commented Apr 20, 2022

The bug with rotating by a PCij matrix that is not a pure rotation has been fixed. It's neat that parametrizing a figure test works.

The figure-test CI builds are currently failing due to a bug that is present in the latest stable release of pytest-mpl (0.14.0).

@ayshih
Copy link
Member Author

ayshih commented Apr 20, 2022

There is a quirk in my implementation here where I allow for order=4 even though OpenCV doesn't implement biquartic, and simply have it use bicubic (i.e., order=4 and order=3 are equivalent). The reason is that I want OpenCV rotation to Just Work with the default for GenericMap.rotate(), which is order=4.

This may be an opportune time to reconsider the change in #1185 (by me, for SunPy 0.7!), and perhaps revert back to a default of order=3. I haven't yet investigated, but maybe the switch in #5867 to defaulting to SciPy mitigates the concerns that had been raised with order=3 as the default. (My comment #1074 (comment) suggests that it would.) (See also #1113)

@ayshih
Copy link
Member Author

ayshih commented Apr 20, 2022

I went ahead and switched GenericMap.rotate() to default to order=3.

@ayshih ayshih force-pushed the opencv branch 3 times, most recently from b9e2aef to 84981c4 Compare April 20, 2022 17:51
@@ -325,8 +346,58 @@ def _rotation_skimage(image, matrix, shift, order, missing, clip):
return rotated_image


@add_rotation_function("cv2", allowed_orders={0, 1, 3},
Copy link
Member

Choose a reason for hiding this comment

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

Why 'cv2' and not 'opencv'?

Copy link
Member Author

Choose a reason for hiding this comment

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

<shrug> Extrapolating from the single point of 'skimage' instead of 'scikit-image', it seems that we are preferring the import name.

Copy link
Contributor

Choose a reason for hiding this comment

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

I also like "cv2" over "opencv".

Copy link
Member

Choose a reason for hiding this comment

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

I really don't like "cv2" it's completely impenetrable to people who haven't used opencv before, unlike opencv it doesn't give you sensible things when you search for it (unlike skimage which is the first result). While it might be the module name, I would argue that whoever decided that you should do import cv2 was also not of sound mind.

Copy link
Member Author

Choose a reason for hiding this comment

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

If I recall correctly, the reason that the package is called cv2 is because they changed the API from their original cv package. It has nothing to do with the version of OpenCV.

If we want, we could actually support both 'cv2' and 'opencv'. We could also support both 'skimage' and 'scikit-image'. Why not!

@ayshih ayshih marked this pull request as ready for review April 20, 2022 20:21
@ayshih ayshih requested review from a team as code owners April 20, 2022 20:21
@ayshih
Copy link
Member Author

ayshih commented Apr 21, 2022

I added an initial commit that preserves @cbard's authorship at some level.

I added (potentially objectionable) scraping of the OpenCV docs to construct the link to their docstring for cv2.warpAffine() for their latest stable version. The link can't be styled exactly the same as intersphinx links, lest it trigger an intersphinx warning due to not having an inventory for cv2.

@ayshih
Copy link
Member Author

ayshih commented Apr 21, 2022

I'll point out that even though the figure-test CI builds are crashing (with pytest-mpl 0.14.0), that's only because the HTML summary page can't be generated when there is mismatch in image dimensions between the baseline and the new images. Once this PR is merged, its images will become the new baseline, so there won't be a persisting crashing of the figure-test CI builds.

@Cadair Cadair self-requested a review April 21, 2022 07:35
@nabobalis nabobalis removed request for a team April 21, 2022 16:25
Copy link
Member

@dstansby dstansby left a comment

Choose a reason for hiding this comment

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

Looks good - I've left some comments that shouldn't block feature freeze, so if they aren't read/replied to by this afternoon I will merge this and open a new issue with my comments.

# In the event of any failure (e.g., no network connectivity)
warpAffine_full = ""

rst_epilog = f"""
Copy link
Member

Choose a reason for hiding this comment

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

Putting this at the end of every .rst file seems a bit much - I presume there's not an easy way to put this just on the pages that it's needed?

Copy link
Member

Choose a reason for hiding this comment

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

It's not particularly an issue putting it everywhere, and putting it everywhere means that you don't have to do anything to use it.

Copy link
Member Author

Choose a reason for hiding this comment

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

A different approach would be to programmatically add it to the specific docstring where it is needed, but that would be fiddly if we ever rename the function or want to use the shortcut in more places. If this showed up in the rendered pages, it'd of course be untenable, but it's essentially invisible to the reader.

changelog/6089.breaking.rst Outdated Show resolved Hide resolved
docs/whatsnew/4.0.rst Outdated Show resolved Hide resolved
sunpy/image/tests/test_transform.py Outdated Show resolved Hide resolved
sunpy/image/tests/test_transform.py Outdated Show resolved Hide resolved
@pytest.mark.parametrize('order', range(6))
def test_endian(method, order, rot30):
if order not in _rotation_registry[method].allowed_orders:
return
Copy link
Member

Choose a reason for hiding this comment

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

Do a pytest.skip with a suitable message here instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, yes, that could be done, but wouldn't that just add noise to the short summary of every test run? There'd always be skips reported because these orders are simply not supported. I'm inclined to consider them passes rather than skips.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am with Albert on this, adding more skip test results at the end of the test output is not something I support especially since we might never be able to unskip them.

sunpy/image/transform.py Outdated Show resolved Hide resolved
Copy link
Member

@Cadair Cadair left a comment

Choose a reason for hiding this comment

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

I am really struggling to get past cv2 over opencv, and the arguments to add_rotation_function should be keyword only arguments.

@ayshih
Copy link
Member Author

ayshih commented Apr 22, 2022

As discussed on Element, the rotation method names have been changed from 'skimage' and 'cv2' to 'scikit-image' and 'opencv'. Since the method keyword was only recently introduced (#5916) and hasn't actually been released, I did not add a changelog entry for the change to the string used to select scikit-image. I wanted to modify that PR's changelog entry anyway because it explicitly stated that scikit-image was the default, but that is changed by this PR.

@cbard
Copy link
Contributor

cbard commented Apr 22, 2022

Thanks to everyone here for their work in getting OpenCV into Sunpy! I also want to acknowledge Raphael Attie (@WaaallEEE), whose work during the HelioHackweek2020 demonstrated the utility of OpenCV as a worthwhile alternative to skimage and scipy and led me to create the original PR #4502.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
image Affects the image submodule map Affects the map submodule No Backport A PR that isn't to be backported to any release branch. (To be used as a flag to other maintainers)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OpenCV as alternative library for map.image.affine_transform
5 participants