测量对象属性
一旦在二值图像中识别出对象(例如,通过连通分量标记),我们就可以从每个对象中提取定量测量值或属性。这些属性对于对象分类、表征和进一步的图像分析至关重要。它们使我们能够以精确的数学方式描述对象的几何形状。
在 scikit-image 库中,skimage.measure.regionprops 函数是实现此目的的强大工具。它以标记图像作为输入(其中每个对象都有一个唯一的整数标签),并返回每个标记区域的属性列表。本节详细介绍了一些可以测量的最常见属性。
面积¶
对象的面积是属于它的像素总数。对于二值对象 ,其数学定义为:
它是衡量对象大小的最基本尺度。
边界框¶
边界框是完全包围对象的最小矩形,其边与图像轴平行。它由其左上角(min_row, min_col)和右下角(max_row, max_col)的坐标定义。这对于在图像中定位对象很有用。
质心¶
质心是对象的几何中心或质心。对于具有 个像素,坐标为 的对象,质心 计算为坐标的平均值:
质心提供一个单点来表示对象的位置。请注意,对于非凸形状,质心可能位于对象本身之外。
离心率¶
离心率是衡量对象偏离完美圆形的程度。通过将一个具有相同二阶矩的椭圆拟合到对象上来计算。离心率是该椭圆的离心率,其值在0到1之间。
其中 和 分别是椭圆的短轴和长轴长度。离心率为0对应于圆形,而接近1的值对应于线段。这对于区分紧凑和细长形状很有用。

离心率图示。红色椭圆与蓝色对象具有相同的二阶矩。对象的离心率定义为该椭圆的离心率。
坚实度¶
坚实度衡量对象的紧凑性。它是对象面积与其凸包面积之比。凸包是包含对象所有点的最小凸多边形。
一个没有凹陷的实心对象的坚实度为1。边界复杂或有孔洞的对象的坚实度值较低。
为清晰起见,图像中对象的凸包用深灰色表示。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from skimage.measure import label, regionprops
from skimage.morphology import label as skimage_label
# 创建一个包含各种形状的示例二值图像
image = np.zeros((200, 200), dtype=np.uint8)
image[10:60, 10:60] = 1 # 正方形
image[10:60, 70:180] = 1 # 矩形
image[70:120, 10:60] = 1 # 另一个正方形
image[80:110, 20:50] = 0 # 在其中制造一个洞
image[130:180, 80:190] = 1 # 一个更大的区域
image[140:170, 90:120] = 0 # 带有一个洞
image[145:165, 130:180] = 1 # 和一个突出部分
# 标记连通分量
labeled_image = skimage_label(image)
# 测量属性
regions = regionprops(labeled_image)
# 显示图像并叠加属性
fig, ax = plt.subplots(1, 1, figsize=(10, 10))
ax.imshow(labeled_image, cmap='nipy_spectral')
for props in regions:
y0, x0 = props.centroid
orientation = props.orientation
x1 = x0 + np.cos(orientation) * 0.5 * props.major_axis_length
y1 = y0 - np.sin(orientation) * 0.5 * props.major_axis_length
x2 = x0 - np.sin(orientation) * 0.5 * props.minor_axis_length
y2 = y0 - np.cos(orientation) * 0.5 * props.minor_axis_length
ax.plot((x0, x1), (y0, y1), '-r', linewidth=2.5)
ax.plot((x0, x2), (y0, y2), '-r', linewidth=2.5)
ax.plot(x0, y0, '.g', markersize=15)
minr, minc, maxr, maxc = props.bbox
bx = (minc, maxc, maxc, minc, minc)
by = (minr, minr, maxr, maxr, minr)
ax.plot(bx, by, '-b', linewidth=2.5)
print(f"区域 {props.label}:")
print(f" 面积: {props.area}")
print(f" 质心: ({y0:.2f}, {x0:.2f})")
print(f" 离心率: {props.eccentricity:.2f}")
print(f" 坚实度: {props.solidity:.2f}")
ax.axis('off')
plt.tight_layout()
plt.show()