标注和测量二值图像中的连通分量
检测连通分量
在二值图像中,连通分量或目标是一组相邻的“on”像素。确定哪些像素是相邻的取决于像素连通性是如何定义的。对于二维图像,有两种标准连通性:
4 连通 - 如果像素的边缘相互接触,则这些像素具有连通性。如果两个相邻像素都为 on 并在水平或垂直方向上连通,则它们是同一目标的一部分。
8 连通 - 如果像素的边缘或角相互接触,则这些像素具有连通性。如果两个相邻像素都为 on 并在水平、垂直或对角线方向上连通,则它们是同一目标的一部分。
您还可以定义非标准连通性,或更高维图像的连通性。有关详细信息,请参阅像素连通性。
该图显示表示二值图像的两个相同的矩阵。每个矩阵上有一个叠加框,分别突出显示了使用 4 连通和 8 连通的连通分量。使用 4 连通有三个连通分量,而使用 8 连通只有两个连通分量。

您可以使用 bwconncomp 函数来计算连通分量。在以下示例代码中,BW 是上图中所示的二值矩阵。对于此示例,将连通性指定为 4,从而当两个相邻像素都为 on 并在水平或垂直方向上连通时,它们将是同一目标的一部分。PixelIdxList 字段标识属于每个连通分量的像素列表。
BW = zeros(8,8); BW(2:4,2:3) = 1; BW(5:7,4:5) = 1; BW(2,6:8) = 1; BW(3,7:8) = 1; BW
BW =
0 0 0 0 0 0 0 0
0 1 1 0 0 1 1 1
0 1 1 0 0 0 1 1
0 1 1 0 0 0 0 0
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0cc4 = bwconncomp(BW,4)
cc4 =
Connectivity: 4
ImageSize: [8 8]
NumObjects: 3
PixelIdxList: {[6x1 double] [6x1 double] [5x1 double]}
为了进行比较,使用默认连通 8 来计算同一个二值图像的连通分量。
cc8 = bwconncomp(BW)
cc8 =
Connectivity: 8
ImageSize: [8 8]
NumObjects: 2
PixelIdxList: {[12x1 double] [5x1 double]}
标注连通分量
连通分量标注是识别图像中的连通分量并为每个分量分配唯一标签的过程。生成的矩阵称为标签矩阵。
此图显示两个标签矩阵,它们分别使用 4 连通和 8 连通来标注连通分量。

使用 labelmatrix 函数创建一个标签矩阵。此示例代码继续使用前一节中定义的连通分量结构体 cc4。
L4 = labelmatrix(cc4)
L4 = 8×8 uint8 matrix 0 0 0 0 0 0 0 0 0 1 1 0 0 3 3 3 0 1 1 0 0 0 3 3 0 1 1 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 2 2 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0
要可视化连通分量,请使用 label2rgb 函数将标签矩阵显示为伪彩色图像。用于标识标签矩阵中每个目标的标签映射到相关联的颜色图中的不同颜色。您可以指定颜色图、背景颜色以及标签矩阵中的目标如何映射到颜色图中的颜色。
RGB_label = label2rgb(L4,@copper,"c","shuffle"); imshow(RGB_label)

选择二值图像中的目标
您可以使用 bwselect 函数选择二值图像中的单个目标。以编程方式或用鼠标以交互方式指定输入图像中的像素。bwselect 返回一个二值图像,该图像仅包含输入图像中包含指定像素之一的那些目标。
例如,使用以下命令选择在当前坐标区中显示的图像中的目标。
BW = bwselect;
光标在位于图像上方时会变为十字准线。点击要选择的目标;bwselect 在您点击的每个像素上显示一个小星形。完成后,按 Return。bwselect 返回由您选择的目标组成的二值图像,并删除小星形。
测量连通分量的属性
regionprops 和 bwpropfilt 函数可以测量连通分量的几个属性。其他函数测量单个属性。例如,bwarea 函数返回二值图像的面积。
此示例使用 bwarea 来确定由膨胀运算导致的 circbw.tif 中面积增加的百分比。面积是图像前景大小的一种测度,大致等于图像中 on 像素的数量。但是,bwarea 不会简单地对设置为 on 的像素数进行计数。bwarea 在计算面积时会对不同像素模式进行不一致的加权。这种加权可以补偿用离散像素表示连续图像所固有的畸变。例如,包含 50 个像素的对角线比包含 50 个像素的水平线长。由于 bwarea 使用加权,水平线的面积为 50,而对角线的面积为 62.5。
BW = imread("circbw.tif");
SE = ones(5);
BW2 = imdilate(BW,SE);
increase = (bwarea(BW2) - bwarea(BW))/bwarea(BW)increase =
0.3456另请参阅
图像区域分析器 | bwconncomp | labelmatrix | label2rgb | bwselect | regionprops | bwpropfilt