标注和度量二值图像中的连通分量
检测连通分量
二值图像中的连通分量或对象是一组相邻像素。确定哪些像素是相邻的取决于像素连通性是如何定义的。对于二维图像,有两种标准连通性:
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 0
cc4 = 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
函数可以返回连通分量的若干属性的测量值。其他函数测量单个属性。例如,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