mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-11 11:42:53 +08:00
Merge pull request #674 from ahojnnes/region-props
Refactor regionprops.
This commit is contained in:
@@ -3,6 +3,7 @@ Version 0.10
|
||||
* Remove deprecated functions:
|
||||
- ``skimage.filter.rank.*``
|
||||
* Remove deprecated parameter ``epsilon`` of ``skimage.viewer.LineProfile``
|
||||
* Remove backwards-compatability of ``skimage.measure.regionprops``
|
||||
|
||||
Version 0.9
|
||||
-----------
|
||||
|
||||
@@ -24,29 +24,23 @@ image[rr,cc] = 1
|
||||
image = rotate(image, angle=15, order=0)
|
||||
|
||||
label_img = label(image)
|
||||
props = regionprops(label_img, [
|
||||
'BoundingBox',
|
||||
'Centroid',
|
||||
'Orientation',
|
||||
'MajorAxisLength',
|
||||
'MinorAxisLength'
|
||||
])
|
||||
regions = regionprops(label_img)
|
||||
|
||||
plt.imshow(image)
|
||||
|
||||
for prop in props:
|
||||
x0 = prop['Centroid'][1]
|
||||
y0 = prop['Centroid'][0]
|
||||
x1 = x0 + math.cos(prop['Orientation']) * 0.5 * prop['MajorAxisLength']
|
||||
y1 = y0 - math.sin(prop['Orientation']) * 0.5 * prop['MajorAxisLength']
|
||||
x2 = x0 - math.sin(prop['Orientation']) * 0.5 * prop['MinorAxisLength']
|
||||
y2 = y0 - math.cos(prop['Orientation']) * 0.5 * prop['MinorAxisLength']
|
||||
for props in regions:
|
||||
y0, x0 = props.centroid
|
||||
orientation = props.orientation
|
||||
x1 = x0 + math.cos(orientation) * 0.5 * props.major_axis_length
|
||||
y1 = y0 - math.sin(orientation) * 0.5 * props.major_axis_length
|
||||
x2 = x0 - math.sin(orientation) * 0.5 * props.minor_axis_length
|
||||
y2 = y0 - math.cos(orientation) * 0.5 * props.minor_axis_length
|
||||
|
||||
plt.plot((x0, x1), (y0, y1), '-r', linewidth=2.5)
|
||||
plt.plot((x0, x2), (y0, y2), '-r', linewidth=2.5)
|
||||
plt.plot(x0, y0, '.g', markersize=15)
|
||||
|
||||
minr, minc, maxr, maxc = prop['BoundingBox']
|
||||
minr, minc, maxr, maxc = props.bbox
|
||||
bx = (minc, maxc, maxc, minc, minc)
|
||||
by = (minr, minr, maxr, maxr, minr)
|
||||
plt.plot(bx, by, '-b', linewidth=2.5)
|
||||
|
||||
@@ -5,7 +5,7 @@ import sys
|
||||
from . import six
|
||||
|
||||
|
||||
__all__ = ['deprecated', 'get_bound_method_class']
|
||||
__all__ = ['deprecated', 'cached_property', 'get_bound_method_class']
|
||||
|
||||
|
||||
class deprecated(object):
|
||||
|
||||
+421
-350
@@ -1,10 +1,11 @@
|
||||
# coding: utf-8
|
||||
import warnings
|
||||
from math import sqrt, atan2, pi as PI
|
||||
import numpy as np
|
||||
from scipy import ndimage
|
||||
|
||||
from skimage.morphology import convex_hull_image
|
||||
from . import _moments
|
||||
from skimage.measure import _moments
|
||||
|
||||
|
||||
__all__ = ['regionprops']
|
||||
@@ -14,47 +15,304 @@ STREL_4 = np.array([[0, 1, 0],
|
||||
[1, 1, 1],
|
||||
[0, 1, 0]])
|
||||
STREL_8 = np.ones((3, 3), 'int8')
|
||||
PROPS = (
|
||||
'Area',
|
||||
'BoundingBox',
|
||||
'CentralMoments',
|
||||
'Centroid',
|
||||
'ConvexArea',
|
||||
PROPS = {
|
||||
'Area': 'area',
|
||||
'BoundingBox': 'bbox',
|
||||
'CentralMoments': 'central_moments',
|
||||
'Centroid': 'centroid',
|
||||
'ConvexArea': 'convex_area',
|
||||
# 'ConvexHull',
|
||||
'ConvexImage',
|
||||
'Coordinates',
|
||||
'Eccentricity',
|
||||
'EquivDiameter',
|
||||
'EulerNumber',
|
||||
'Extent',
|
||||
'ConvexImage': 'convex_image',
|
||||
'Coordinates': 'coords',
|
||||
'Eccentricity': 'eccentricity',
|
||||
'EquivDiameter': 'equivalent_diameter',
|
||||
'EulerNumber': 'euler_number',
|
||||
'Extent': 'extent',
|
||||
# 'Extrema',
|
||||
'FilledArea',
|
||||
'FilledImage',
|
||||
'HuMoments',
|
||||
'Image',
|
||||
'MajorAxisLength',
|
||||
'MaxIntensity',
|
||||
'MeanIntensity',
|
||||
'MinIntensity',
|
||||
'MinorAxisLength',
|
||||
'Moments',
|
||||
'NormalizedMoments',
|
||||
'Orientation',
|
||||
'Perimeter',
|
||||
'FilledArea': 'filled_area',
|
||||
'FilledImage': 'filled_image',
|
||||
'HuMoments': 'hu_moments',
|
||||
'Image': 'image',
|
||||
'MajorAxisLength': 'major_axis_length',
|
||||
'MaxIntensity': 'max_intensity',
|
||||
'MeanIntensity': 'mean_intensity',
|
||||
'MinIntensity': 'min_intensity',
|
||||
'MinorAxisLength': 'minor_axis_length',
|
||||
'Moments': 'moments',
|
||||
'NormalizedMoments': 'normalized_moments',
|
||||
'Orientation': 'orientation',
|
||||
'Perimeter': 'perimeter',
|
||||
# 'PixelIdxList',
|
||||
# 'PixelList',
|
||||
'Solidity',
|
||||
'Solidity': 'solidity',
|
||||
# 'SubarrayIdx'
|
||||
'WeightedCentralMoments',
|
||||
'WeightedCentroid',
|
||||
'WeightedHuMoments',
|
||||
'WeightedMoments',
|
||||
'WeightedNormalizedMoments'
|
||||
)
|
||||
'WeightedCentralMoments': 'weighted_central_moments',
|
||||
'WeightedCentroid': 'weighted_centroid',
|
||||
'WeightedHuMoments': 'weighted_hu_moments',
|
||||
'WeightedMoments': 'weighted_moments',
|
||||
'WeightedNormalizedMoments': 'weighted_normalized_moments'
|
||||
}
|
||||
|
||||
|
||||
def regionprops(label_image, properties=['Area', 'Centroid'],
|
||||
intensity_image=None):
|
||||
class cached_property(object):
|
||||
"""Decorator to use a function as a cached property.
|
||||
|
||||
The function is only called the first time and each successive call returns
|
||||
the cached result of the first call.
|
||||
|
||||
class Foo(object):
|
||||
|
||||
@cached_property
|
||||
def foo(self):
|
||||
return "Cached"
|
||||
|
||||
class Foo(object):
|
||||
|
||||
def __init__(self):
|
||||
self.cache_active = False
|
||||
|
||||
@cached_property
|
||||
def foo(self):
|
||||
return "Not cached"
|
||||
|
||||
Adapted from <http://wiki.python.org/moin/PythonDecoratorLibrary>.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, func, name=None, doc=None):
|
||||
self.__name__ = name or func.__name__
|
||||
self.__module__ = func.__module__
|
||||
self.__doc__ = doc or func.__doc__
|
||||
self.func = func
|
||||
|
||||
def __get__(self, obj, type=None):
|
||||
if obj is None:
|
||||
return self
|
||||
|
||||
# call every time, if cache is not active
|
||||
if not obj.__dict__.get('cache_active', True):
|
||||
return self.func(obj)
|
||||
|
||||
# try to retrieve from cache or call and store result in cache
|
||||
try:
|
||||
value = obj.__dict__[self.__name__]
|
||||
except KeyError:
|
||||
value = self.func(obj)
|
||||
obj.__dict__[self.__name__] = value
|
||||
return value
|
||||
|
||||
|
||||
class _RegionProperties(object):
|
||||
|
||||
def __init__(self, slice, label, label_image, intensity_image,
|
||||
cache_active):
|
||||
self._slice = slice
|
||||
self.label = label
|
||||
self._label_image = label_image
|
||||
self._intensity_image = intensity_image
|
||||
self.cache_active = cache_active
|
||||
|
||||
@cached_property
|
||||
def area(self):
|
||||
return self.moments[0, 0]
|
||||
|
||||
@cached_property
|
||||
def bbox(self):
|
||||
return (self._slice[0].start, self._slice[1].start,
|
||||
self._slice[0].stop, self._slice[1].stop)
|
||||
|
||||
@cached_property
|
||||
def centroid(self):
|
||||
row, col = self.local_centroid
|
||||
return row + self._slice[0].start, col + self._slice[1].start
|
||||
|
||||
@cached_property
|
||||
def central_moments(self):
|
||||
row, col = self.local_centroid
|
||||
return _moments.central_moments(self._image_double, row, col, 3)
|
||||
|
||||
@cached_property
|
||||
def convex_area(self):
|
||||
return np.sum(self.convex_image)
|
||||
|
||||
@cached_property
|
||||
def convex_image(self):
|
||||
return convex_hull_image(self.image)
|
||||
|
||||
@cached_property
|
||||
def coords(self):
|
||||
rr, cc = np.nonzero(self.image)
|
||||
return np.vstack((rr + self._slice[0].start,
|
||||
cc + self._slice[1].start)).T
|
||||
|
||||
@cached_property
|
||||
def eccentricity(self):
|
||||
l1, l2 = self.inertia_tensor_eigvals
|
||||
if l1 == 0:
|
||||
return 0
|
||||
return sqrt(1 - l2 / l1)
|
||||
|
||||
@cached_property
|
||||
def equivalent_diameter(self):
|
||||
return sqrt(4 * self.moments[0, 0] / PI)
|
||||
|
||||
@cached_property
|
||||
def euler_number(self):
|
||||
euler_array = self.filled_image != self.image
|
||||
_, num = ndimage.label(euler_array, STREL_8)
|
||||
return -num
|
||||
|
||||
@cached_property
|
||||
def extent(self):
|
||||
rows, cols = self.image.shape
|
||||
return self.moments[0, 0] / (rows * cols)
|
||||
|
||||
@cached_property
|
||||
def filled_area(self):
|
||||
return np.sum(self.filled_image)
|
||||
|
||||
@cached_property
|
||||
def filled_image(self):
|
||||
return ndimage.binary_fill_holes(self.image, STREL_8)
|
||||
|
||||
@cached_property
|
||||
def hu_moments(self):
|
||||
return _moments.hu_moments(self.normalized_moments)
|
||||
|
||||
@cached_property
|
||||
def image(self):
|
||||
return self._label_image[self._slice] == self.label
|
||||
|
||||
@cached_property
|
||||
def _image_double(self):
|
||||
return self.image.astype(np.double)
|
||||
|
||||
@cached_property
|
||||
def inertia_tensor(self):
|
||||
mu = self.central_moments
|
||||
a = mu[2, 0] / mu[0, 0]
|
||||
b = -mu[1, 1] / mu[0, 0]
|
||||
c = mu[0, 2] / mu[0, 0]
|
||||
return np.array([[a, b], [b, c]])
|
||||
|
||||
@cached_property
|
||||
def inertia_tensor_eigvals(self):
|
||||
a, b, b, c = self.inertia_tensor.flat
|
||||
# eigen values of inertia tensor
|
||||
l1 = (a + c) / 2 + sqrt(4 * b ** 2 + (a - c) ** 2) / 2
|
||||
l2 = (a + c) / 2 - sqrt(4 * b ** 2 + (a - c) ** 2) / 2
|
||||
return l1, l2
|
||||
|
||||
@cached_property
|
||||
def intensity_image(self):
|
||||
if self._intensity_image is None:
|
||||
raise AttributeError('No intensity image specified.')
|
||||
return self._intensity_image[self._slice] * self.image
|
||||
|
||||
@cached_property
|
||||
def _intensity_image_double(self):
|
||||
return self.intensity_image.astype(np.double)
|
||||
|
||||
@cached_property
|
||||
def moments(self):
|
||||
return _moments.central_moments(self._image_double, 0, 0, 3)
|
||||
|
||||
@cached_property
|
||||
def local_centroid(self):
|
||||
m = self.moments
|
||||
row = m[0, 1] / m[0, 0]
|
||||
col = m[1, 0] / m[0, 0]
|
||||
return row, col
|
||||
|
||||
@cached_property
|
||||
def max_intensity(self):
|
||||
return np.max(self.intensity_image[self.image])
|
||||
|
||||
@cached_property
|
||||
def mean_intensity(self):
|
||||
return np.mean(self.intensity_image[self.image])
|
||||
|
||||
@cached_property
|
||||
def min_intensity(self):
|
||||
return np.min(self.intensity_image[self.image])
|
||||
|
||||
@cached_property
|
||||
def major_axis_length(self):
|
||||
l1, _ = self.inertia_tensor_eigvals
|
||||
return 4 * sqrt(l1)
|
||||
|
||||
@cached_property
|
||||
def minor_axis_length(self):
|
||||
_, l2 = self.inertia_tensor_eigvals
|
||||
return 4 * sqrt(l2)
|
||||
|
||||
@cached_property
|
||||
def normalized_moments(self):
|
||||
return _moments.normalized_moments(self.central_moments, 3)
|
||||
|
||||
@cached_property
|
||||
def orientation(self):
|
||||
a, b, b, c = self.inertia_tensor.flat
|
||||
b = -b
|
||||
if a - c == 0:
|
||||
if b > 0:
|
||||
return -PI / 4.
|
||||
else:
|
||||
return PI / 4.
|
||||
else:
|
||||
return - 0.5 * atan2(2 * b, (a - c))
|
||||
|
||||
@cached_property
|
||||
def perimeter(self):
|
||||
return perimeter(self.image, 4)
|
||||
|
||||
@cached_property
|
||||
def solidity(self):
|
||||
return self.moments[0, 0] / np.sum(self.convex_image)
|
||||
|
||||
@cached_property
|
||||
def weighted_central_moments(self):
|
||||
row, col = self.weighted_local_centroid
|
||||
return _moments.central_moments(self._intensity_image_double,
|
||||
row, col, 3)
|
||||
|
||||
@cached_property
|
||||
def weighted_centroid(self):
|
||||
row, col = self.weighted_local_centroid
|
||||
return row + self._slice[0].start, col + self._slice[1].start
|
||||
|
||||
@cached_property
|
||||
def weighted_local_centroid(self):
|
||||
m = self.weighted_moments
|
||||
row = m[0, 1] / m[0, 0]
|
||||
col = m[1, 0] / m[0, 0]
|
||||
return row, col
|
||||
|
||||
@cached_property
|
||||
def weighted_hu_moments(self):
|
||||
return _moments.hu_moments(self.weighted_normalized_moments)
|
||||
|
||||
@cached_property
|
||||
def weighted_moments(self):
|
||||
return _moments.central_moments(self._intensity_image_double, 0, 0, 3)
|
||||
|
||||
@cached_property
|
||||
def weighted_normalized_moments(self):
|
||||
return _moments.normalized_moments(self.weighted_central_moments, 3)
|
||||
|
||||
def __getitem__(self, key):
|
||||
value = getattr(self, key, None)
|
||||
if value is not None:
|
||||
return value
|
||||
else: # backwards compatability
|
||||
warnings.warn('Usage of deprecated property name.',
|
||||
category=DeprecationWarning)
|
||||
return getattr(self, PROPS[key])
|
||||
|
||||
|
||||
|
||||
def regionprops(label_image, properties=None,
|
||||
intensity_image=None, cache=True):
|
||||
"""Measure properties of labelled image regions.
|
||||
|
||||
Parameters
|
||||
@@ -62,150 +320,128 @@ def regionprops(label_image, properties=['Area', 'Centroid'],
|
||||
label_image : (N, M) ndarray
|
||||
Labelled input image.
|
||||
properties : {'all', list}
|
||||
Shape measurements to be determined for each labelled image region.
|
||||
Default is `['Area', 'Centroid']`. The following properties can be
|
||||
determined:
|
||||
**Deprecated parameter**
|
||||
|
||||
* Area : int
|
||||
Number of pixels of region.
|
||||
|
||||
* BoundingBox : tuple
|
||||
Bounding box `(min_row, min_col, max_row, max_col)`
|
||||
|
||||
* CentralMoments : (3, 3) ndarray
|
||||
Central moments (translation invariant) up to 3rd order.
|
||||
|
||||
mu_ji = sum{ array(x, y) * (x - x_c)^j * (y - y_c)^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region,
|
||||
and `x_c` and `y_c` are the coordinates of the region's centroid.
|
||||
|
||||
* Centroid : array
|
||||
Centroid coordinate tuple `(row, col)`.
|
||||
|
||||
* ConvexArea : int
|
||||
Number of pixels of convex hull image.
|
||||
|
||||
* ConvexImage : (H, J) ndarray
|
||||
Binary convex hull image which has the same size as bounding box.
|
||||
|
||||
* Coordinates : (N, 2) ndarray
|
||||
Coordinate list `(row, col)` of the region.
|
||||
|
||||
* Eccentricity : float
|
||||
Eccentricity of the ellipse that has the same second-moments as the
|
||||
region. The eccentricity is the ratio of the distance between its
|
||||
minor and major axis length. The value is between 0 and 1.
|
||||
|
||||
* EquivDiameter : float
|
||||
The diameter of a circle with the same area as the region.
|
||||
|
||||
* EulerNumber : int
|
||||
Euler number of region. Computed as number of objects (= 1)
|
||||
subtracted by number of holes (8-connectivity).
|
||||
|
||||
* Extent : float
|
||||
Ratio of pixels in the region to pixels in the total bounding box.
|
||||
Computed as `Area / (rows*cols)`
|
||||
|
||||
* FilledArea : int
|
||||
Number of pixels of filled region.
|
||||
|
||||
* FilledImage : (H, J) ndarray
|
||||
Binary region image with filled holes which has the same size as
|
||||
bounding box.
|
||||
|
||||
* HuMoments : tuple
|
||||
Hu moments (translation, scale and rotation invariant).
|
||||
|
||||
* Image : (H, J) ndarray
|
||||
Sliced binary region image which has the same size as bounding box.
|
||||
|
||||
* MajorAxisLength : float
|
||||
The length of the major axis of the ellipse that has the same
|
||||
normalized second central moments as the region.
|
||||
|
||||
* MaxIntensity: float
|
||||
Value with the greatest intensity in the region.
|
||||
|
||||
* MeanIntensity: float
|
||||
Value with the mean intensity in the region.
|
||||
|
||||
* MinIntensity: float
|
||||
Value with the least intensity in the region.
|
||||
|
||||
* MinorAxisLength : float
|
||||
The length of the minor axis of the ellipse that has the same
|
||||
normalized second central moments as the region.
|
||||
|
||||
* Moments : (3, 3) ndarray
|
||||
Spatial moments up to 3rd order.
|
||||
|
||||
m_ji = sum{ array(x, y) * x^j * y^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region.
|
||||
|
||||
* NormalizedMoments : (3, 3) ndarray
|
||||
Normalized moments (translation and scale invariant) up to 3rd
|
||||
order.
|
||||
|
||||
nu_ji = mu_ji / m_00^[(i+j)/2 + 1]
|
||||
|
||||
where `m_00` is the zeroth spatial moment.
|
||||
|
||||
* Orientation : float
|
||||
Angle between the X-axis and the major axis of the ellipse that has
|
||||
the same second-moments as the region. Ranging from `-pi/2` to
|
||||
`pi/2` in counter-clockwise direction.
|
||||
|
||||
* Perimeter : float
|
||||
Perimeter of object which approximates the contour as a line
|
||||
through the centers of border pixels using a 4-connectivity.
|
||||
|
||||
* Solidity : float
|
||||
Ratio of pixels in the region to pixels of the convex hull image.
|
||||
|
||||
* WeightedCentralMoments : (3, 3) ndarray
|
||||
Central moments (translation invariant) of intensity image up to
|
||||
3rd order.
|
||||
|
||||
wmu_ji = sum{ array(x, y) * (x - x_c)^j * (y - y_c)^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region,
|
||||
and `x_c` and `y_c` are the coordinates of the region's centroid.
|
||||
|
||||
* WeightedCentroid : array
|
||||
Centroid coordinate tuple `(row, col)` weighted with intensity
|
||||
image.
|
||||
|
||||
* WeightedHuMoments : tuple
|
||||
Hu moments (translation, scale and rotation invariant) of intensity
|
||||
image.
|
||||
|
||||
* WeightedMoments : (3, 3) ndarray
|
||||
Spatial moments of intensity image up to 3rd order.
|
||||
|
||||
wm_ji = sum{ array(x, y) * x^j * y^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region.
|
||||
|
||||
* WeightedNormalizedMoments : (3, 3) ndarray
|
||||
Normalized moments (translation and scale invariant) of intensity
|
||||
image up to 3rd order.
|
||||
|
||||
wnu_ji = wmu_ji / wm_00^[(i+j)/2 + 1]
|
||||
|
||||
where `wm_00` is the zeroth spatial moment (intensity-weighted
|
||||
area).
|
||||
This parameter is not needed any more since all properties are
|
||||
determined dynamically.
|
||||
|
||||
intensity_image : (N, M) ndarray, optional
|
||||
Intensity image with same size as labelled image. Default is None.
|
||||
cache : bool, optional
|
||||
Determine whether to cache calculated properties. The computation is
|
||||
much faster for cached properties, whereas the memory consumption
|
||||
increases.
|
||||
|
||||
Returns
|
||||
-------
|
||||
properties : list of dicts
|
||||
List containing a property dict for each region. The property dicts
|
||||
contain all the specified properties plus a 'Label' field.
|
||||
properties : list
|
||||
List containing a properties for each region. The properties of each
|
||||
region can be accessed as attributes and keys.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The following properties can be accessed as attributes or keys:
|
||||
|
||||
area : int
|
||||
Number of pixels of region.
|
||||
bbox : tuple
|
||||
Bounding box `(min_row, min_col, max_row, max_col)`
|
||||
central_moments : (3, 3) ndarray
|
||||
Central moments (translation invariant) up to 3rd order::
|
||||
|
||||
mu_ji = sum{ array(x, y) * (x - x_c)^j * (y - y_c)^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region,
|
||||
and `x_c` and `y_c` are the coordinates of the region's centroid.
|
||||
centroid : array
|
||||
Centroid coordinate tuple `(row, col)`.
|
||||
convex_area : int
|
||||
Number of pixels of convex hull image.
|
||||
convex_image : (H, J) ndarray
|
||||
Binary convex hull image which has the same size as bounding box.
|
||||
coords : (N, 2) ndarray
|
||||
Coordinate list `(row, col)` of the region.
|
||||
eccentricity : float
|
||||
Eccentricity of the ellipse that has the same second-moments as the
|
||||
region. The eccentricity is the ratio of the distance between its
|
||||
minor and major axis length. The value is between 0 and 1.
|
||||
equivalent_diameter : float
|
||||
The diameter of a circle with the same area as the region.
|
||||
euler_number : int
|
||||
Euler number of region. Computed as number of objects (= 1)
|
||||
subtracted by number of holes (8-connectivity).
|
||||
extent : float
|
||||
Ratio of pixels in the region to pixels in the total bounding box.
|
||||
Computed as `Area / (rows*cols)`
|
||||
filled_area : int
|
||||
Number of pixels of filled region.
|
||||
filled_image : (H, J) ndarray
|
||||
Binary region image with filled holes which has the same size as
|
||||
bounding box.
|
||||
hu_moments : tuple
|
||||
Hu moments (translation, scale and rotation invariant).
|
||||
image : (H, J) ndarray
|
||||
Sliced binary region image which has the same size as bounding box.
|
||||
major_axis_length : float
|
||||
The length of the major axis of the ellipse that has the same
|
||||
normalized second central moments as the region.
|
||||
min_intensity : float
|
||||
Value with the greatest intensity in the region.
|
||||
mean_intensity : float
|
||||
Value with the mean intensity in the region.
|
||||
min_intensity : float
|
||||
Value with the least intensity in the region.
|
||||
minor_axis_length : float
|
||||
The length of the minor axis of the ellipse that has the same
|
||||
normalized second central moments as the region.
|
||||
moments : (3, 3) ndarray
|
||||
Spatial moments up to 3rd order::
|
||||
|
||||
m_ji = sum{ array(x, y) * x^j * y^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region.
|
||||
normalized_moments : (3, 3) ndarray
|
||||
Normalized moments (translation and scale invariant) up to 3rd order::
|
||||
|
||||
nu_ji = mu_ji / m_00^[(i+j)/2 + 1]
|
||||
|
||||
where `m_00` is the zeroth spatial moment.
|
||||
orientation : float
|
||||
Angle between the X-axis and the major axis of the ellipse that has
|
||||
the same second-moments as the region. Ranging from `-pi/2` to
|
||||
`pi/2` in counter-clockwise direction.
|
||||
perimeter : float
|
||||
Perimeter of object which approximates the contour as a line
|
||||
through the centers of border pixels using a 4-connectivity.
|
||||
solidity : float
|
||||
Ratio of pixels in the region to pixels of the convex hull image.
|
||||
weighted_central_moments : (3, 3) ndarray
|
||||
Central moments (translation invariant) of intensity image up to
|
||||
3rd order::
|
||||
|
||||
wmu_ji = sum{ array(x, y) * (x - x_c)^j * (y - y_c)^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region,
|
||||
and `x_c` and `y_c` are the coordinates of the region's centroid.
|
||||
weighted_centroid : array
|
||||
Centroid coordinate tuple `(row, col)` weighted with intensity
|
||||
image.
|
||||
weighted_hu_moments : tuple
|
||||
Hu moments (translation, scale and rotation invariant) of intensity
|
||||
image.
|
||||
weighted_moments : (3, 3) ndarray
|
||||
Spatial moments of intensity image up to 3rd order::
|
||||
|
||||
wm_ji = sum{ array(x, y) * x^j * y^i }
|
||||
|
||||
where the sum is over the `x`, `y` coordinates of the region.
|
||||
weighted_normalized_moments : (3, 3) ndarray
|
||||
Normalized moments (translation and scale invariant) of intensity
|
||||
image up to 3rd order::
|
||||
|
||||
wnu_ji = wmu_ji / wm_00^[(i+j)/2 + 1]
|
||||
|
||||
where `wm_00` is the zeroth spatial moment (intensity-weighted area).
|
||||
|
||||
References
|
||||
----------
|
||||
@@ -225,194 +461,29 @@ def regionprops(label_image, properties=['Area', 'Centroid'],
|
||||
>>> img = coins() > 110
|
||||
>>> label_img = label(img)
|
||||
>>> props = regionprops(label_img)
|
||||
>>> props[0]['Centroid'] # centroid of first labelled object
|
||||
>>> props[0].centroid # centroid of first labelled object
|
||||
>>> props[0]['centroid'] # centroid of first labelled object
|
||||
"""
|
||||
if not np.issubdtype(label_image.dtype, 'int'):
|
||||
raise TypeError('labelled image must be of integer dtype')
|
||||
raise TypeError('Labelled image must be of integer dtype.')
|
||||
|
||||
# determine all properties if nothing specified
|
||||
if properties == 'all':
|
||||
properties = PROPS
|
||||
if properties is not None:
|
||||
warnings.warn('The ``properties`` argument is deprecated and is '
|
||||
'not needed any more as properties are '
|
||||
'determined dynamically.',
|
||||
category=DeprecationWarning)
|
||||
|
||||
props = []
|
||||
regions = []
|
||||
|
||||
objects = ndimage.find_objects(label_image)
|
||||
for i, sl in enumerate(objects):
|
||||
label = i + 1
|
||||
|
||||
# create property dict for current label
|
||||
obj_props = {}
|
||||
props.append(obj_props)
|
||||
props = _RegionProperties(sl, label, label_image,
|
||||
intensity_image, cache)
|
||||
regions.append(props)
|
||||
|
||||
obj_props['Label'] = label
|
||||
|
||||
array = (label_image[sl] == label).astype('double')
|
||||
|
||||
# upper left corner of object bbox
|
||||
r0 = sl[0].start
|
||||
c0 = sl[1].start
|
||||
|
||||
m = _moments.central_moments(array, 0, 0, 3)
|
||||
# centroid
|
||||
cr = m[0, 1] / m[0, 0]
|
||||
cc = m[1, 0] / m[0, 0]
|
||||
mu = _moments.central_moments(array, cr, cc, 3)
|
||||
|
||||
# elements of the inertia tensor [a b; b c]
|
||||
a = mu[2, 0] / mu[0, 0]
|
||||
b = mu[1, 1] / mu[0, 0]
|
||||
c = mu[0, 2] / mu[0, 0]
|
||||
# eigen values of inertia tensor
|
||||
l1 = (a + c) / 2 + sqrt(4 * b ** 2 + (a - c) ** 2) / 2
|
||||
l2 = (a + c) / 2 - sqrt(4 * b ** 2 + (a - c) ** 2) / 2
|
||||
|
||||
# cached results which are used by several properties
|
||||
_filled_image = None
|
||||
_convex_image = None
|
||||
_nu = None
|
||||
|
||||
if 'Area' in properties:
|
||||
obj_props['Area'] = m[0, 0]
|
||||
|
||||
if 'BoundingBox' in properties:
|
||||
obj_props['BoundingBox'] = (r0, c0, sl[0].stop, sl[1].stop)
|
||||
|
||||
if 'Centroid' in properties:
|
||||
obj_props['Centroid'] = cr + r0, cc + c0
|
||||
|
||||
if 'CentralMoments' in properties:
|
||||
obj_props['CentralMoments'] = mu
|
||||
|
||||
if 'ConvexArea' in properties:
|
||||
if _convex_image is None:
|
||||
_convex_image = convex_hull_image(array)
|
||||
obj_props['ConvexArea'] = np.sum(_convex_image)
|
||||
|
||||
if 'ConvexImage' in properties:
|
||||
if _convex_image is None:
|
||||
_convex_image = convex_hull_image(array)
|
||||
obj_props['ConvexImage'] = _convex_image
|
||||
|
||||
if 'Coordinates' in properties:
|
||||
rr, cc = np.nonzero(array)
|
||||
obj_props['Coordinates'] = np.vstack((rr + r0, cc + c0)).T
|
||||
|
||||
if 'Eccentricity' in properties:
|
||||
if l1 == 0:
|
||||
obj_props['Eccentricity'] = 0
|
||||
else:
|
||||
obj_props['Eccentricity'] = sqrt(1 - l2 / l1)
|
||||
|
||||
if 'EquivDiameter' in properties:
|
||||
obj_props['EquivDiameter'] = sqrt(4 * m[0, 0] / PI)
|
||||
|
||||
if 'EulerNumber' in properties:
|
||||
if _filled_image is None:
|
||||
_filled_image = ndimage.binary_fill_holes(array, STREL_8)
|
||||
euler_array = _filled_image != array
|
||||
_, num = ndimage.label(euler_array, STREL_8)
|
||||
obj_props['EulerNumber'] = - num
|
||||
|
||||
if 'Extent' in properties:
|
||||
obj_props['Extent'] = m[0, 0] / (array.shape[0] * array.shape[1])
|
||||
|
||||
if 'HuMoments' in properties:
|
||||
if _nu is None:
|
||||
_nu = _moments.normalized_moments(mu, 3)
|
||||
obj_props['HuMoments'] = _moments.hu_moments(_nu)
|
||||
|
||||
if 'Image' in properties:
|
||||
obj_props['Image'] = array
|
||||
|
||||
if 'FilledArea' in properties:
|
||||
if _filled_image is None:
|
||||
_filled_image = ndimage.binary_fill_holes(array, STREL_8)
|
||||
obj_props['FilledArea'] = np.sum(_filled_image)
|
||||
|
||||
if 'FilledImage' in properties:
|
||||
if _filled_image is None:
|
||||
_filled_image = ndimage.binary_fill_holes(array, STREL_8)
|
||||
obj_props['FilledImage'] = _filled_image
|
||||
|
||||
if 'MajorAxisLength' in properties:
|
||||
obj_props['MajorAxisLength'] = 4 * sqrt(l1)
|
||||
|
||||
if 'MinorAxisLength' in properties:
|
||||
obj_props['MinorAxisLength'] = 4 * sqrt(l2)
|
||||
|
||||
if 'Moments' in properties:
|
||||
obj_props['Moments'] = m
|
||||
|
||||
if 'NormalizedMoments' in properties:
|
||||
if _nu is None:
|
||||
_nu = _moments.normalized_moments(mu, 3)
|
||||
obj_props['NormalizedMoments'] = _nu
|
||||
|
||||
if 'Orientation' in properties:
|
||||
if a - c == 0:
|
||||
if b > 0:
|
||||
obj_props['Orientation'] = -PI / 4.
|
||||
else:
|
||||
obj_props['Orientation'] = PI / 4.
|
||||
else:
|
||||
obj_props['Orientation'] = - 0.5 * atan2(2 * b, (a - c))
|
||||
|
||||
if 'Perimeter' in properties:
|
||||
obj_props['Perimeter'] = perimeter(array, 4)
|
||||
|
||||
if 'Solidity' in properties:
|
||||
if _convex_image is None:
|
||||
_convex_image = convex_hull_image(array)
|
||||
obj_props['Solidity'] = m[0, 0] / np.sum(_convex_image)
|
||||
|
||||
if intensity_image is not None:
|
||||
weighted_array = array * intensity_image[sl]
|
||||
|
||||
wm = _moments.central_moments(weighted_array, 0, 0, 3)
|
||||
# weighted centroid
|
||||
wcr = wm[0, 1] / wm[0, 0]
|
||||
wcc = wm[1, 0] / wm[0, 0]
|
||||
wmu = _moments.central_moments(weighted_array, wcr, wcc, 3)
|
||||
|
||||
# cached results which are used by several properties
|
||||
_wnu = None
|
||||
_vals = None
|
||||
|
||||
if 'MaxIntensity' in properties:
|
||||
if _vals is None:
|
||||
_vals = weighted_array[array.astype('bool')]
|
||||
obj_props['MaxIntensity'] = np.max(_vals)
|
||||
|
||||
if 'MeanIntensity' in properties:
|
||||
if _vals is None:
|
||||
_vals = weighted_array[array.astype('bool')]
|
||||
obj_props['MeanIntensity'] = np.mean(_vals)
|
||||
|
||||
if 'MinIntensity' in properties:
|
||||
if _vals is None:
|
||||
_vals = weighted_array[array.astype('bool')]
|
||||
obj_props['MinIntensity'] = np.min(_vals)
|
||||
|
||||
if 'WeightedCentralMoments' in properties:
|
||||
obj_props['WeightedCentralMoments'] = wmu
|
||||
|
||||
if 'WeightedCentroid' in properties:
|
||||
obj_props['WeightedCentroid'] = wcr + r0, wcc + c0
|
||||
|
||||
if 'WeightedHuMoments' in properties:
|
||||
if _wnu is None:
|
||||
_wnu = _moments.normalized_moments(wmu, 3)
|
||||
obj_props['WeightedHuMoments'] = _moments.hu_moments(_wnu)
|
||||
|
||||
if 'WeightedMoments' in properties:
|
||||
obj_props['WeightedMoments'] = wm
|
||||
|
||||
if 'WeightedNormalizedMoments' in properties:
|
||||
if _wnu is None:
|
||||
_wnu = _moments.normalized_moments(wmu, 3)
|
||||
obj_props['WeightedNormalizedMoments'] = _wnu
|
||||
|
||||
return props
|
||||
return regions
|
||||
|
||||
|
||||
def perimeter(image, neighbourhood=4):
|
||||
|
||||
@@ -22,33 +22,33 @@ INTENSITY_SAMPLE = SAMPLE.copy()
|
||||
INTENSITY_SAMPLE[1, 9:11] = 2
|
||||
|
||||
|
||||
def test_all_props():
|
||||
regions = regionprops(SAMPLE, 'all', INTENSITY_SAMPLE)[0]
|
||||
for prop in PROPS:
|
||||
regions[prop]
|
||||
|
||||
|
||||
def test_unsupported_dtype():
|
||||
assert_raises(TypeError, regionprops, np.zeros((10, 10), dtype=np.double))
|
||||
|
||||
|
||||
def test_all_props():
|
||||
props = regionprops(SAMPLE, 'all', INTENSITY_SAMPLE)[0]
|
||||
for prop in PROPS:
|
||||
assert prop in props
|
||||
|
||||
|
||||
def test_area():
|
||||
area = regionprops(SAMPLE, ['Area'])[0]['Area']
|
||||
area = regionprops(SAMPLE)[0].area
|
||||
assert area == np.sum(SAMPLE)
|
||||
|
||||
|
||||
def test_bbox():
|
||||
bbox = regionprops(SAMPLE, ['BoundingBox'])[0]['BoundingBox']
|
||||
bbox = regionprops(SAMPLE)[0].bbox
|
||||
assert_array_almost_equal(bbox, (0, 0, SAMPLE.shape[0], SAMPLE.shape[1]))
|
||||
|
||||
SAMPLE_mod = SAMPLE.copy()
|
||||
SAMPLE_mod[:, -1] = 0
|
||||
bbox = regionprops(SAMPLE_mod, ['BoundingBox'])[0]['BoundingBox']
|
||||
bbox = regionprops(SAMPLE_mod)[0].bbox
|
||||
assert_array_almost_equal(bbox, (0, 0, SAMPLE.shape[0], SAMPLE.shape[1]-1))
|
||||
|
||||
|
||||
def test_central_moments():
|
||||
mu = regionprops(SAMPLE, ['CentralMoments'])[0]['CentralMoments']
|
||||
mu = regionprops(SAMPLE)[0].central_moments
|
||||
# determined with OpenCV
|
||||
assert_almost_equal(mu[0,2], 436.00000000000045)
|
||||
# different from OpenCV results, bug in OpenCV
|
||||
@@ -61,19 +61,19 @@ def test_central_moments():
|
||||
|
||||
|
||||
def test_centroid():
|
||||
centroid = regionprops(SAMPLE, ['Centroid'])[0]['Centroid']
|
||||
centroid = regionprops(SAMPLE)[0].centroid
|
||||
# determined with MATLAB
|
||||
assert_array_almost_equal(centroid, (5.66666666666666, 9.444444444444444))
|
||||
|
||||
|
||||
def test_convex_area():
|
||||
area = regionprops(SAMPLE, ['ConvexArea'])[0]['ConvexArea']
|
||||
area = regionprops(SAMPLE)[0].convex_area
|
||||
# determined with MATLAB
|
||||
assert area == 124
|
||||
|
||||
|
||||
def test_convex_image():
|
||||
img = regionprops(SAMPLE, ['ConvexImage'])[0]['ConvexImage']
|
||||
img = regionprops(SAMPLE)[0].convex_image
|
||||
# determined with MATLAB
|
||||
ref = np.array(
|
||||
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
|
||||
@@ -94,43 +94,43 @@ def test_coordinates():
|
||||
sample = np.zeros((10, 10), dtype=np.int8)
|
||||
coords = np.array([[3, 2], [3, 3], [3, 4]])
|
||||
sample[coords[:, 0], coords[:, 1]] = 1
|
||||
prop_coords = regionprops(sample, ['Coordinates'])[0]['Coordinates']
|
||||
prop_coords = regionprops(sample)[0].coords
|
||||
assert_array_equal(prop_coords, coords)
|
||||
|
||||
|
||||
def test_eccentricity():
|
||||
eps = regionprops(SAMPLE, ['Eccentricity'])[0]['Eccentricity']
|
||||
eps = regionprops(SAMPLE)[0].eccentricity
|
||||
assert_almost_equal(eps, 0.814629313427)
|
||||
|
||||
img = np.zeros((5, 5), dtype=np.int)
|
||||
img[2, 2] = 1
|
||||
eps = regionprops(img, ['Eccentricity'])[0]['Eccentricity']
|
||||
eps = regionprops(img)[0].eccentricity
|
||||
assert_almost_equal(eps, 0)
|
||||
|
||||
|
||||
def test_equiv_diameter():
|
||||
diameter = regionprops(SAMPLE, ['EquivDiameter'])[0]['EquivDiameter']
|
||||
diameter = regionprops(SAMPLE)[0].equivalent_diameter
|
||||
# determined with MATLAB
|
||||
assert_almost_equal(diameter, 9.57461472963)
|
||||
|
||||
|
||||
def test_euler_number():
|
||||
en = regionprops(SAMPLE, ['EulerNumber'])[0]['EulerNumber']
|
||||
en = regionprops(SAMPLE)[0].euler_number
|
||||
assert en == 0
|
||||
|
||||
SAMPLE_mod = SAMPLE.copy()
|
||||
SAMPLE_mod[7, -3] = 0
|
||||
en = regionprops(SAMPLE_mod, ['EulerNumber'])[0]['EulerNumber']
|
||||
en = regionprops(SAMPLE_mod)[0].euler_number
|
||||
assert en == -1
|
||||
|
||||
|
||||
def test_extent():
|
||||
extent = regionprops(SAMPLE, ['Extent'])[0]['Extent']
|
||||
extent = regionprops(SAMPLE)[0].extent
|
||||
assert_almost_equal(extent, 0.4)
|
||||
|
||||
|
||||
def test_hu_moments():
|
||||
hu = regionprops(SAMPLE, ['HuMoments'])[0]['HuMoments']
|
||||
hu = regionprops(SAMPLE)[0].hu_moments
|
||||
ref = np.array([
|
||||
3.27117627e-01,
|
||||
2.63869194e-02,
|
||||
@@ -145,59 +145,59 @@ def test_hu_moments():
|
||||
|
||||
|
||||
def test_image():
|
||||
img = regionprops(SAMPLE, ['Image'])[0]['Image']
|
||||
img = regionprops(SAMPLE)[0].image
|
||||
assert_array_equal(img, SAMPLE)
|
||||
|
||||
|
||||
def test_filled_area():
|
||||
area = regionprops(SAMPLE, ['FilledArea'])[0]['FilledArea']
|
||||
area = regionprops(SAMPLE)[0].filled_area
|
||||
assert area == np.sum(SAMPLE)
|
||||
|
||||
SAMPLE_mod = SAMPLE.copy()
|
||||
SAMPLE_mod[7, -3] = 0
|
||||
area = regionprops(SAMPLE_mod, ['FilledArea'])[0]['FilledArea']
|
||||
area = regionprops(SAMPLE_mod)[0].filled_area
|
||||
assert area == np.sum(SAMPLE)
|
||||
|
||||
|
||||
def test_filled_image():
|
||||
img = regionprops(SAMPLE, ['FilledImage'])[0]['FilledImage']
|
||||
img = regionprops(SAMPLE)[0].filled_image
|
||||
assert_array_equal(img, SAMPLE)
|
||||
|
||||
|
||||
def test_major_axis_length():
|
||||
length = regionprops(SAMPLE, ['MajorAxisLength'])[0]['MajorAxisLength']
|
||||
length = regionprops(SAMPLE)[0].major_axis_length
|
||||
# MATLAB has different interpretation of ellipse than found in literature,
|
||||
# here implemented as found in literature
|
||||
assert_almost_equal(length, 16.7924234999)
|
||||
|
||||
|
||||
def test_max_intensity():
|
||||
intensity = regionprops(SAMPLE, ['MaxIntensity'], INTENSITY_SAMPLE
|
||||
)[0]['MaxIntensity']
|
||||
intensity = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].max_intensity
|
||||
assert_almost_equal(intensity, 2)
|
||||
|
||||
|
||||
def test_mean_intensity():
|
||||
intensity = regionprops(SAMPLE, ['MeanIntensity'], INTENSITY_SAMPLE
|
||||
)[0]['MeanIntensity']
|
||||
intensity = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].mean_intensity
|
||||
assert_almost_equal(intensity, 1.02777777777777)
|
||||
|
||||
|
||||
def test_min_intensity():
|
||||
intensity = regionprops(SAMPLE, ['MinIntensity'], INTENSITY_SAMPLE
|
||||
)[0]['MinIntensity']
|
||||
intensity = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].min_intensity
|
||||
assert_almost_equal(intensity, 1)
|
||||
|
||||
|
||||
def test_minor_axis_length():
|
||||
length = regionprops(SAMPLE, ['MinorAxisLength'])[0]['MinorAxisLength']
|
||||
length = regionprops(SAMPLE)[0].minor_axis_length
|
||||
# MATLAB has different interpretation of ellipse than found in literature,
|
||||
# here implemented as found in literature
|
||||
assert_almost_equal(length, 9.739302807263)
|
||||
|
||||
|
||||
def test_moments():
|
||||
m = regionprops(SAMPLE, ['Moments'])[0]['Moments']
|
||||
m = regionprops(SAMPLE)[0].moments
|
||||
# determined with OpenCV
|
||||
assert_almost_equal(m[0,0], 72.0)
|
||||
assert_almost_equal(m[0,1], 408.0)
|
||||
@@ -212,7 +212,7 @@ def test_moments():
|
||||
|
||||
|
||||
def test_normalized_moments():
|
||||
nu = regionprops(SAMPLE, ['NormalizedMoments'])[0]['NormalizedMoments']
|
||||
nu = regionprops(SAMPLE)[0].normalized_moments
|
||||
# determined with OpenCV
|
||||
assert_almost_equal(nu[0,2], 0.08410493827160502)
|
||||
assert_almost_equal(nu[1,1], -0.016846707818929982)
|
||||
@@ -223,29 +223,26 @@ def test_normalized_moments():
|
||||
|
||||
|
||||
def test_orientation():
|
||||
orientation = regionprops(SAMPLE, ['Orientation'])[0]['Orientation']
|
||||
orientation = regionprops(SAMPLE)[0].orientation
|
||||
# determined with MATLAB
|
||||
assert_almost_equal(orientation, 0.10446844651921)
|
||||
# test correct quadrant determination
|
||||
orientation2 = regionprops(SAMPLE.T, ['Orientation'])[0]['Orientation']
|
||||
orientation2 = regionprops(SAMPLE.T)[0].orientation
|
||||
assert_almost_equal(orientation2, math.pi / 2 - orientation)
|
||||
# test diagonal regions
|
||||
diag = np.eye(10, dtype=int)
|
||||
orientation_diag = regionprops(diag, ['Orientation'])[0]['Orientation']
|
||||
orientation_diag = regionprops(diag)[0].orientation
|
||||
assert_almost_equal(orientation_diag, -math.pi / 4)
|
||||
orientation_diag = regionprops(np.flipud(diag), ['Orientation']
|
||||
)[0]['Orientation']
|
||||
orientation_diag = regionprops(np.flipud(diag))[0].orientation
|
||||
assert_almost_equal(orientation_diag, math.pi / 4)
|
||||
orientation_diag = regionprops(np.fliplr(diag), ['Orientation']
|
||||
)[0]['Orientation']
|
||||
orientation_diag = regionprops(np.fliplr(diag))[0].orientation
|
||||
assert_almost_equal(orientation_diag, math.pi / 4)
|
||||
orientation_diag = regionprops(np.fliplr(np.flipud(diag)), ['Orientation']
|
||||
)[0]['Orientation']
|
||||
orientation_diag = regionprops(np.fliplr(np.flipud(diag)))[0].orientation
|
||||
assert_almost_equal(orientation_diag, -math.pi / 4)
|
||||
|
||||
|
||||
def test_perimeter():
|
||||
per = regionprops(SAMPLE, ['Perimeter'])[0]['Perimeter']
|
||||
per = regionprops(SAMPLE)[0].perimeter
|
||||
assert_almost_equal(per, 55.2487373415)
|
||||
|
||||
per = perimeter(SAMPLE.astype('double'), neighbourhood=8)
|
||||
@@ -253,14 +250,14 @@ def test_perimeter():
|
||||
|
||||
|
||||
def test_solidity():
|
||||
solidity = regionprops(SAMPLE, ['Solidity'])[0]['Solidity']
|
||||
solidity = regionprops(SAMPLE)[0].solidity
|
||||
# determined with MATLAB
|
||||
assert_almost_equal(solidity, 0.580645161290323)
|
||||
|
||||
|
||||
def test_weighted_central_moments():
|
||||
wmu = regionprops(SAMPLE, ['WeightedCentralMoments'], INTENSITY_SAMPLE
|
||||
)[0]['WeightedCentralMoments']
|
||||
wmu = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].weighted_central_moments
|
||||
ref = np.array(
|
||||
[[ 7.4000000000e+01, -2.1316282073e-13, 4.7837837838e+02,
|
||||
-7.5943608473e+02],
|
||||
@@ -276,14 +273,14 @@ def test_weighted_central_moments():
|
||||
|
||||
|
||||
def test_weighted_centroid():
|
||||
centroid = regionprops(SAMPLE, ['WeightedCentroid'], INTENSITY_SAMPLE
|
||||
)[0]['WeightedCentroid']
|
||||
centroid = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].weighted_centroid
|
||||
assert_array_almost_equal(centroid, (5.540540540540, 9.445945945945))
|
||||
|
||||
|
||||
def test_weighted_hu_moments():
|
||||
whu = regionprops(SAMPLE, ['WeightedHuMoments'], INTENSITY_SAMPLE
|
||||
)[0]['WeightedHuMoments']
|
||||
whu = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].weighted_hu_moments
|
||||
ref = np.array([
|
||||
3.1750587329e-01,
|
||||
2.1417517159e-02,
|
||||
@@ -297,8 +294,8 @@ def test_weighted_hu_moments():
|
||||
|
||||
|
||||
def test_weighted_moments():
|
||||
wm = regionprops(SAMPLE, ['WeightedMoments'], INTENSITY_SAMPLE
|
||||
)[0]['WeightedMoments']
|
||||
wm = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].weighted_moments
|
||||
ref = np.array(
|
||||
[[ 7.4000000000e+01, 4.1000000000e+02, 2.7500000000e+03,
|
||||
1.9778000000e+04],
|
||||
@@ -313,8 +310,8 @@ def test_weighted_moments():
|
||||
|
||||
|
||||
def test_weighted_normalized_moments():
|
||||
wnu = regionprops(SAMPLE, ['WeightedNormalizedMoments'], INTENSITY_SAMPLE
|
||||
)[0]['WeightedNormalizedMoments']
|
||||
wnu = regionprops(SAMPLE, intensity_image=INTENSITY_SAMPLE
|
||||
)[0].weighted_normalized_moments
|
||||
ref = np.array(
|
||||
[[ np.nan, np.nan, 0.0873590903, -0.0161217406],
|
||||
[ np.nan, -0.0160405109, -0.0031421072, -0.0031376984],
|
||||
|
||||
Reference in New Issue
Block a user