Skip to content

Commit

Permalink
Fix failing regionprop_table for multichannel properties (#6861)
Browse files Browse the repository at this point in the history
* Add test for multichannel weighted centroid
* Return table is a dict, not a dataframe
* Check shape with np.shape to support array-likes
* test shape for rp0 as well as rp1 and rpm

Co-authored-by: Lars Grüter <lagru+github@mailbox.org>
  • Loading branch information
jni and lagru committed Apr 4, 2023
1 parent 70c3fd8 commit 64e5ff8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
11 changes: 4 additions & 7 deletions skimage/measure/_regionprops.py
Expand Up @@ -854,15 +854,10 @@ def _props_to_dict(regions, properties=('label', 'bbox'), separator='-'):
column_buffer[i] = regions[i][prop]
out[orig_prop] = np.copy(column_buffer)
else:
if isinstance(rp, np.ndarray):
shape = rp.shape
else:
shape = (len(rp),)

# precompute property column names and locations
modified_props = []
locs = []
for ind in np.ndindex(shape):
for ind in np.ndindex(np.shape(rp)):
modified_props.append(
separator.join(map(str, (orig_prop,) + ind))
)
Expand All @@ -872,7 +867,9 @@ def _props_to_dict(regions, properties=('label', 'bbox'), separator='-'):
n_columns = len(locs)
column_data = np.empty((n, n_columns), dtype=dtype)
for k in range(n):
rp = regions[k][prop]
# we coerce to a numpy array to ensure structures like
# tuple-of-arrays expand correctly into columns
rp = np.asarray(regions[k][prop])
for i, loc in enumerate(locs):
column_data[k, i] = rp[loc]

Expand Down
24 changes: 24 additions & 0 deletions skimage/measure/tests/test_regionprops.py
Expand Up @@ -33,6 +33,9 @@
INTENSITY_SAMPLE = SAMPLE.copy()
INTENSITY_SAMPLE[1, 9:11] = 2
INTENSITY_FLOAT_SAMPLE = INTENSITY_SAMPLE.copy().astype(np.float64) / 10.0
INTENSITY_FLOAT_SAMPLE_MULTICHANNEL = (
INTENSITY_FLOAT_SAMPLE[..., np.newaxis] * [1, 2, 3]
)

SAMPLE_MULTIPLE = np.eye(10, dtype=np.int32)
SAMPLE_MULTIPLE[3:5, 7:8] = 2
Expand Down Expand Up @@ -714,6 +717,27 @@ def test_solidity():
assert_almost_equal(solidity, target_solidity)


def test_multichannel_centroid_weighted_table():
"""Test for https://github.com/scikit-image/scikit-image/issues/6860."""
intensity_image = INTENSITY_FLOAT_SAMPLE_MULTICHANNEL
rp0 = regionprops(SAMPLE, intensity_image=intensity_image[..., 0])[0]
rp1 = regionprops(SAMPLE, intensity_image=intensity_image[..., 0:1])[0]
rpm = regionprops(SAMPLE, intensity_image=intensity_image)[0]
np.testing.assert_almost_equal(rp0.centroid_weighted,
np.squeeze(rp1.centroid_weighted))
np.testing.assert_almost_equal(rp0.centroid_weighted,
np.array(rpm.centroid_weighted)[:, 0])
assert np.shape(rp0.centroid_weighted) == (SAMPLE.ndim,)
assert np.shape(rp1.centroid_weighted) == (SAMPLE.ndim, 1)
assert np.shape(rpm.centroid_weighted) == (SAMPLE.ndim,
intensity_image.shape[-1])

table = regionprops_table(SAMPLE, intensity_image=intensity_image,
properties=('centroid_weighted',))
# check the number of returned columns is correct
assert len(table) == np.size(rpm.centroid_weighted)


def test_moments_weighted_central():
wmu = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
)[0].moments_weighted_central
Expand Down

0 comments on commit 64e5ff8

Please sign in to comment.