按要求实现matlab中bwlabel的功能。本方法是基于图的广度,深度优先遍历。
% 找二值图像中联通区域的个数,以及大小 % 算法思想: % 在图像中找到一个目标点(可以是自顶向下、从左到右的第一个目标点), % 然后采用图的搜索方法,找出与该目标点连通的区域。 % 对该连通区域进行标记(相当于将该目标区域变成背景) % 重复上述过程,直到找不到目标点(整幅图像扫描完毕) % 关键算法:找出与一个目标点连通的区域 % 采用图的搜索算法。 % 设置一个open表(待搜素的结点表),将种子点放入该表中。 % 从open表中取出一个元素,将其邻域中以前未搜索到的目标点加入到open表中。 % 重复上述过程,直到open表为空。 % 关键数据结构: % visited[rows][cols], 用于记录各个像素点是否被访问过(搜索过,1;未访问过,0) % 在下面程序中,注意使用不同的语句带来的程序运行效率差别 % 程序优化 % 比较不同写法的程序执行效率差别 % I=imread('rice.png'); % I=imread('moon.tif'); % I=imread('moon.tif'); % I=imread('rice.png'); % I=imread('paper1.tif'); % I=imread('concordorthophoto.png'); I=imread('liftingbody.png'); % I=imread('rice4.bmp'); % I=imread('test500.bmp'); [rows,cols]=size(I); BW=im2bw(I); % figure,imshow(BW); regions=0; visited=zeros(rows,cols); tic %tStart = tic; for i=1:rows for j=1:cols if BW(i,j)==0 || visited(i,j)==1 continue; end open_table=[i,j]; regions=regions+1; num=1; visited(i,j)=1; % open_table 表是否为空的不同判断方法 比较 % while length(open_table)>0 while ~isempty(open_table) p=open_table(1,1); q=open_table(1,2); open_table=open_table(2:end,:); for r=max(1,p-1):min(p+1,rows) for c=max(1,q-1):min(q+1,cols) % 比较两个条件的排放顺序对效率的影响 % if BW(r,c)==1 && visited(r,c)==0 if visited(r,c)==0 && BW(r,c)==1 % 还可比较在此处用if来判断(r,c)是否超出图像边界 % 与直接使用 r=max(1,p-1):min(p+1,rows)的效率 visited(r,c)=1; % 扩展结点加在表头,还是表尾的差别 % 对于一个连通区域大的图像,如 moon.tif, 两者的差别很大 % 放在表头,运行效率低。可能是在表头加一个元素,整个表中的数据都要移动; % 而加在表尾,则没有这一问题 % 另一种做法:建立一个长表,用headp,tailp,表示表头和表尾的位置。在表头取元素 % 在表尾加元素 % open_table=[r,c;open_table]; open_table=[open_table;r,c]; num=num+1; end end end end nums(regions)=num; end end toc; %tElapsed = toc(tStart);