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 spacing to regionprops and moments. #6296

Merged
merged 15 commits into from Apr 7, 2022

Conversation

tibuch
Copy link
Contributor

@tibuch tibuch commented Mar 21, 2022

Description

Enhancement, closes #5112.

Checklist

For reviewers

  • Check that the PR title is short, concise, and will make sense 1 year
    later.
  • Check that new functions are imported in corresponding __init__.py.
  • Check that new features, API changes, and deprecations are mentioned in
    doc/release/release_dev.rst.
  • There is a bot to help automate backporting a PR to an older branch. For
    example, to backport to v0.19.x after merging, add the following in a PR
    comment: @meeseeksdev backport to v0.19.x
  • To run benchmarks on a PR, add the run-benchmark label. To rerun, the label
    can be removed and then added again. The benchmark output can be checked in
    the "Actions" tab.

@pep8speaks
Copy link

pep8speaks commented Mar 21, 2022

Hello @tibuch! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

Line 195:80: E501 line too long (82 > 79 characters)
Line 255:17: E126 continuation line over-indented for hanging indent
Line 255:80: E501 line too long (85 > 79 characters)
Line 320:80: E501 line too long (99 > 79 characters)
Line 391:80: E501 line too long (82 > 79 characters)
Line 428:80: E501 line too long (96 > 79 characters)

Line 306:80: E501 line too long (85 > 79 characters)
Line 546:80: E501 line too long (83 > 79 characters)
Line 553:80: E501 line too long (90 > 79 characters)
Line 560:80: E501 line too long (84 > 79 characters)
Line 585:80: E501 line too long (85 > 79 characters)
Line 592:80: E501 line too long (85 > 79 characters)
Line 622:80: E501 line too long (80 > 79 characters)
Line 638:80: E501 line too long (85 > 79 characters)
Line 644:80: E501 line too long (90 > 79 characters)
Line 651:80: E501 line too long (84 > 79 characters)
Line 866:80: E501 line too long (86 > 79 characters)
Line 1002:80: E501 line too long (90 > 79 characters)
Line 1017:80: E501 line too long (94 > 79 characters)
Line 1093:80: E501 line too long (84 > 79 characters)
Line 1095:80: E501 line too long (92 > 79 characters)
Line 1323:80: E501 line too long (91 > 79 characters)

Line 27:1: E302 expected 2 blank lines, found 1

Line 50:80: E501 line too long (94 > 79 characters)
Line 56:80: E501 line too long (86 > 79 characters)
Line 57:80: E501 line too long (82 > 79 characters)
Line 58:80: E501 line too long (97 > 79 characters)
Line 65:80: E501 line too long (94 > 79 characters)
Line 143:80: E501 line too long (85 > 79 characters)
Line 150:80: E501 line too long (95 > 79 characters)
Line 153:80: E501 line too long (80 > 79 characters)
Line 156:61: W504 line break after binary operator
Line 165:80: E501 line too long (91 > 79 characters)
Line 166:80: E501 line too long (90 > 79 characters)
Line 168:80: E501 line too long (94 > 79 characters)
Line 170:80: E501 line too long (83 > 79 characters)
Line 173:38: W504 line break after binary operator
Line 174:38: W504 line break after binary operator
Line 177:38: W504 line break after binary operator
Line 178:38: W504 line break after binary operator
Line 181:38: W504 line break after binary operator
Line 182:38: W504 line break after binary operator
Line 209:80: E501 line too long (81 > 79 characters)
Line 211:80: E501 line too long (81 > 79 characters)
Line 661:80: E501 line too long (88 > 79 characters)
Line 778:80: E501 line too long (106 > 79 characters)
Line 786:80: E501 line too long (106 > 79 characters)
Line 873:80: E501 line too long (111 > 79 characters)

Comment last updated at 2022-04-04 07:12:59 UTC

@grlee77 grlee77 added the ⏩ type: Enhancement Improve existing features label Mar 21, 2022
@grlee77
Copy link
Contributor

grlee77 commented Mar 21, 2022

Thanks @tibuch, we are very keen to have this functionality. I will try to review this soon

Copy link
Member

@jni jni left a comment

Choose a reason for hiding this comment

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

@tibuch awesome! Thank you for tackling this, apologies that I never got round to it! 😅 I really appreciate it. I have made a couple of suggestions, most are nitpicky and I would consider optional for approval, but the ones I really care about are adding indices or coords_scaled as a property (since coords are in many cases used for indexing so you don't want the scaling), and removing pixel_area as a property since it is a property of the image, not the region, and trivial to compute outside of the function.

Thank you again!

skimage/measure/_regionprops.py Outdated Show resolved Hide resolved
skimage/measure/_regionprops.py Show resolved Hide resolved
skimage/measure/_regionprops.py Show resolved Hide resolved
Comment on lines 1277 to 1284
'Non-integer image types are ambiguous: '
'use skimage.measure.label to label the connected'
'components of label_image,'
'or label_image.astype(np.uint8) to interpret'
'the True values as a single label.')
else:
raise TypeError(
'Non-integer label_image types are ambiguous')
'Non-integer label_image types are ambiguous')
Copy link
Member

Choose a reason for hiding this comment

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

Do you mind reverting unrelated formatting changes? They will make git-blame harder to follow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I hope I caught all of them 😇

@@ -198,51 +338,75 @@ def test_coordinates():
prop_coords = regionprops(sample)[0].coords
assert_array_equal(prop_coords, coords)

spacing = (1, 0.5)
prop_coords = regionprops(sample, spacing=spacing)[0].coords
assert_array_equal(prop_coords, coords * np.array(spacing))
Copy link
Member

Choose a reason for hiding this comment

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

For all of these tests, I'd prefer if there was a separate test function for unit spacing, isotropic spacing, and anisotropic spacing, perhaps using pytest.parametrize? It makes it much easier to find failing tests in the future...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense.

You will also notice that not all features are tested with anisotropy, because I could not find reference numbers. Do you know of some implementations that could be used?

Copy link
Member

Choose a reason for hiding this comment

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

I don't. Typically I would try to hand-check the numbers (going step by step in the implementation) and then save those as a reference. Or you can derive some from first principles, for example, drawing an ellipse with a particular orientation using skimage.draw, then taking away every other row of pixels and using spacing=(2, 1) and making sure that the results are close to the isotropic case.

Copy link
Member

@jni jni left a comment

Choose a reason for hiding this comment

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

I'm approving, but will let this sit for a few days to give others a chance to review and @tibuch a chance to investigate some of the additional tests if possible. Thank you again @tibuch!

Copy link
Contributor

@grlee77 grlee77 left a comment

Choose a reason for hiding this comment

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

Thanks @tibuch, this is looking pretty good. I just had some small fixes and suggestions.

skimage/measure/_regionprops.py Outdated Show resolved Hide resolved
skimage/measure/_regionprops.py Outdated Show resolved Hide resolved
skimage/measure/_moments.py Outdated Show resolved Hide resolved
skimage/measure/_regionprops.py Show resolved Hide resolved
@tibuch
Copy link
Contributor Author

tibuch commented Mar 31, 2022

I implemented the requested changes.

Additionally I found that the normalized moments were wrong. Could you have a close look at this commit: 41322934dcfbb5db74b98e369d8264997465a43a

Thanks!

@jni
Copy link
Member

jni commented Apr 1, 2022

Nice catch @tibuch! Looks good to me.

It looks like the tolerance on some of the tests needs to be reduced to decimal=0, unfortunately. I think that's fine. This is one of the failures. Since it doesn't fail in every Python version or OS, I guess it is machine-dependent. But still looks right to me.

>       assert_almost_equal(length, target_length, decimal=1)
E       AssertionError: 
E       Arrays are not almost equal to 1 decimals
E        ACTUAL: 17.955520462276805
E        DESIRED: 17.73962515156774

@tibuch
Copy link
Contributor Author

tibuch commented Apr 4, 2022

Don't know why these are failing:

=========================== short test summary info ============================
FAILED scikit-image/skimage/data/tests/test_data.py::test_eagle - ValueError:...
FAILED scikit-image/skimage/io/tests/test_pil.py::test_imread_index_png_with_alpha
FAILED scikit-image/skimage/io/tests/test_pil.py::test_extreme_palette - Valu...
===== 3 failed, 8076 passed, 15 skipped, 24 warnings in 290.59s (0:04:50) ======

@jni
Copy link
Member

jni commented Apr 4, 2022

Pillow 9.1 was released Apr 1 so I presume that is the culprit, nothing to do with your work @tibuch!

@jni
Copy link
Member

jni commented Apr 4, 2022

Yeah, see #6314

@alexdesiqueira
Copy link
Member

Thank you @tibuch! How do you like this one after the changes, @grlee77?

Copy link
Contributor

@grlee77 grlee77 left a comment

Choose a reason for hiding this comment

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

Thanks, @tibuch. The tests are looking good now. Thank you for fixing the normalized moments. I may take a quick look about using pytest.parametrize as @jni requested, but that is just a test style concern, so I wil go ahead and approve now.

@grlee77 grlee77 merged commit 6ac7c80 into scikit-image:main Apr 7, 2022
@tibuch
Copy link
Contributor Author

tibuch commented Oct 5, 2022

Hi,

I was wondering when this code will make it into an official release?

Cheers

@lagru
Copy link
Member

lagru commented Oct 5, 2022

Hey @tibuch. We've just started with the preparation of the next release 0.20. We are not certain on the precise target date yet but somewhere around 2022-10-24. You can follow along our 0.20 milestone if you want to stay informed on the progress.

@lagru lagru added this to the 0.20 milestone Oct 5, 2022
rapids-bot bot pushed a commit to rapidsai/cucim that referenced this pull request Nov 16, 2022
…d regionprops (#422)

related to #419

This PR ports features related to image moments and `regionprops` from scikit-image 0.20 to cuCIM

- Improve performance of ``cucim.skimage.measure.moments_central`` by ~2x by avoiding redundant computations (adaptation of scikit-image/scikit-image#6188 to the GPU)
- Support anisotropic images with different voxel spacings.  Spacings can be defined with the new parameter ``spacing`` of the following functions in ``skimage.measure``: ``regionprops``, ``regionprops_table``, ``moments``, ``moments_central``, ``moments_normalized``, ``centroid``, ``inertia_tensor``, and ``inertia_tensor_eigvals`` (scikit-image/scikit-image#6296)
- Voxel spacing is taken into account for the following existing properties in ``skimage.measure.regionprops``: ``area``, ``area_bbox``, ``centroid``, ``area_convex``, ``extent``, ``feret_diameter_max``, ``area_filled``, ``inertia_tensor``, ``moments``, ``moments_central``, ``moments_hu``, ``moments_normalized``, ``perimeter``, ``perimeter_crofton``, ``solidity``, ``moments_weighted_central``, and ``moments_weighted_hu``. (scikit-image/scikit-image#6296)
- Raise a specific error message when accessing region properties from skimage.measure.regionprops when the required intensity_image is unavailable (scikit-image/scikit-image#6584).

Authors:
  - Gregory Lee (https://github.com/grlee77)

Approvers:
  - Gigon Bae (https://github.com/gigony)

URL: #422
@imagesc-bot
Copy link

This pull request has been mentioned on Image.sc Forum. There might be relevant details there:

https://forum.image.sc/t/scaling-regionprops-for-non-isotropic-images/61971/5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⏩ type: Enhancement Improve existing features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: add voxel spacing to skimage.measure.regionprops
7 participants