Description
This follows up on #8312, but separates the remaining normalization question
from that issue's expectation of exact equality across different raster
resolutions.
On current main (457ef06), moments_central applies each axis's spacing to
the coordinates, while moments_normalized reduces the spacing tuple to
min(spacing) and divides a moment of total order q by
min(spacing) ** q.
The current choice is homogeneous in length, so it correctly preserves the
existing documented/tested behavior when all spacing values are multiplied
by the same scalar. The narrower question is whether using the smallest pixel
edge is the intended scalar normalization for anisotropic data.
For a continuous-density interpretation, let d be the number of dimensions,
q = sum(p) the total moment order, and V = prod(spacing) the voxel volume.
The corresponding continuous moments are approximated by
M_p ~= V * mu_p and M_0 ~= V * mu_0.
Substituting these into the usual normalized central moment gives
eta_p ~= mu_p / (mu_0 ** (1 + q / d) * V ** (q / d)).
This uses the geometric-mean spacing V ** (1 / d) as the scalar length
scale. It reduces to the current expression for isotropic spacing, but differs
from min(spacing) for anisotropic grids.
Reproducible example
import numpy as np
from skimage.measure import moments_central, moments_normalized
image = np.ones((200, 400), dtype=float)
spacing = (0.01, 0.02)
mu = moments_central(image, spacing=spacing)
nu = moments_normalized(mu, spacing=spacing)
q = 2
d = image.ndim
voxel_volume = np.prod(spacing)
nu_volume_aware = mu[0, 2] / (
mu[0, 0] ** (1 + q / d) * voxel_volume ** (q / d)
)
height = image.shape[0] * spacing[0]
width = image.shape[1] * spacing[1]
continuous_rectangle = width / (12 * height)
print(nu[0, 2]) # 0.6666625 with min(spacing)
print(nu_volume_aware) # 0.33333125
print(continuous_rectangle) # 0.3333333333333333
Here the sampled rectangle has physical height 2 and width 8. The
volume-aware discrete value approaches the continuous rectangle's normalized
second moment as the grid is refined, whereas the min(spacing) value retains
a factor determined by the spacing anisotropy.
This is not a request for exact equality between differently sampled
rasters. Point-sampled discrete moments have resolution-dependent quadrature
error, so such equality is not generally achievable without finite-pixel
integration corrections.
Question and proposed scope
Is min(spacing) intentionally defining normalized moments relative to the
finest pixel edge? If so, documenting that convention and its implications for
anisotropic data would make the API contract clearer.
If continuous-density semantics are intended instead, would replacing the
scalar factor with prod(spacing) ** (q / d) be appropriate? A focused PR
could preserve the existing common-rescaling test, add 2D/3D checks against
the explicit volume-weighted formula, and document the observable output
change for anisotropic spacing.
The current min(spacing) expression was introduced in #6296. I could not
find discussion of the scalar-spacing choice in that PR's public review.
AI assistance disclosure: Codex was used to inspect the implementation and
history, check the algebra and numerical example, and help draft this report.
The cited source, history, duplicate search, and numerical outputs were checked
against current main before posting.
Description
This follows up on #8312, but separates the remaining normalization question
from that issue's expectation of exact equality across different raster
resolutions.
On current
main(457ef06),moments_centralapplies each axis's spacing tothe coordinates, while
moments_normalizedreduces the spacing tuple tomin(spacing)and divides a moment of total orderqbymin(spacing) ** q.The current choice is homogeneous in length, so it correctly preserves the
existing documented/tested behavior when all spacing values are multiplied
by the same scalar. The narrower question is whether using the smallest pixel
edge is the intended scalar normalization for anisotropic data.
For a continuous-density interpretation, let
dbe the number of dimensions,q = sum(p)the total moment order, andV = prod(spacing)the voxel volume.The corresponding continuous moments are approximated by
M_p ~= V * mu_pandM_0 ~= V * mu_0.Substituting these into the usual normalized central moment gives
eta_p ~= mu_p / (mu_0 ** (1 + q / d) * V ** (q / d)).This uses the geometric-mean spacing
V ** (1 / d)as the scalar lengthscale. It reduces to the current expression for isotropic spacing, but differs
from
min(spacing)for anisotropic grids.Reproducible example
Here the sampled rectangle has physical height 2 and width 8. The
volume-aware discrete value approaches the continuous rectangle's normalized
second moment as the grid is refined, whereas the
min(spacing)value retainsa factor determined by the spacing anisotropy.
This is not a request for exact equality between differently sampled
rasters. Point-sampled discrete moments have resolution-dependent quadrature
error, so such equality is not generally achievable without finite-pixel
integration corrections.
Question and proposed scope
Is
min(spacing)intentionally defining normalized moments relative to thefinest pixel edge? If so, documenting that convention and its implications for
anisotropic data would make the API contract clearer.
If continuous-density semantics are intended instead, would replacing the
scalar factor with
prod(spacing) ** (q / d)be appropriate? A focused PRcould preserve the existing common-rescaling test, add 2D/3D checks against
the explicit volume-weighted formula, and document the observable output
change for anisotropic spacing.
The current
min(spacing)expression was introduced in #6296. I could notfind discussion of the scalar-spacing choice in that PR's public review.
AI assistance disclosure: Codex was used to inspect the implementation and
history, check the algebra and numerical example, and help draft this report.
The cited source, history, duplicate search, and numerical outputs were checked
against current
mainbefore posting.