基本思路:
- 二值化后前景图像以1进行标记,背景图像标记为0。
- 遍历原图I,当遇到前景图像时,判断该前景图像是否被标记,若该像素点pix(i,j)未被标记,则保存其坐标值至队列中,并在标记矩阵的对应坐标位置对该像素点进行标记。
- 对pix(i,j)的八个邻域进行搜索,当遇到新的未被标记的前景像素点时,将该点p(i+1,j)(或是其他点)坐标值入列,并在标记矩阵中进行标记。
- 八个邻域搜索标记完成后,将pix(i,j)出列,此时列头为pix(i+1,j),再次进行步骤3的八邻域搜索及标记操作。
- 当一个连通区域标记完成后,标签计数加一,清空队列,再次进行步骤2~4的遍历等操作,标记新的连通区域。
源码:
function IMG = label_blob(I)
%图像连通区域标记
%输入:灰度图矩阵 (可用Matlab自带图像 rice.png 进行测试
%输出:图像内连通区域数量
%%
%二值化
L = I > 130;
[row,col] = size(L);
%标记连通图像
connected = zeros(row,col);
queue = [];
label = 2;
%8邻域坐标
offsets = [-1 -1; -1 0; -1 1; 0 -1; 0 1; 1 -1; 1 0; 1 1];
%%
for i = 1:row
for j = 1:col
if L(i,j) == 1 && connected(i,j) == 0
connected(i,j) = label;
if isempty(queue)
queue = [i;j];
else
queue = [queue [i;j]];
end
while ~isempty(queue)
pix = [queue(1,1),queue(2,1)];
%8邻域搜索
for k = 1:8
%邻域坐标 (外加获得
n_pix = bsxfun(@plus,pix,offsets(k,:));
%判断邻域坐标是否在范围内
if n_pix(1) >= 1 && n_pix(1) <= row && n_pix(2) >= 1 && n_pix(2) <= col
%像素值为1且未被标记
if L(n_pix(1),n_pix(2)) == 1 && connected(n_pix(1),n_pix(2)) == 0
connected(n_pix(1),n_pix(2)) = label;
%邻域坐标入列
queue = [queue [n_pix(1);n_pix(2)]];
end
end
end
queue(:,1) = [];
end
%标记加1以进行下一区域搜索
label = label + 1;
end
end
end
%连通区域数
num = label - 2;
%%
%输出显示
%imshow(I);
IMG = mat2gray(connected);
%figure,imshow(IMG);