连通分量的提取
实际上,在二值图像中提取连通分量是许多自动图像分析应用中的核心任务。 令 Y 表示一个包含于集合 A 中的连通分量,并假设 Y 中的一个点 p 是已知的。而后,用下列的迭代表达式生成 Y 的所有元素:
代码实例
clear all; close all; clc; img=imread('shape.bmp'); [m n]=size(img); imshow(img); [x y]=ginput(); result=zeros(m,n); x=round(x); y=round(y); result(x,y)=0; tmp=ones(m,n); queue_head=1; %队列头 queue_tail=1; %队列尾 neighbour=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1]; %和当前像素坐标相加得到八个邻域坐标 %neighbour=[-1 0;1 0;0 1;0 -1]; %四邻域用的 q{queue_tail}=[y x]; queue_tail=queue_tail+1; [ser1 ser2]=size(neighbour); while queue_head~=queue_tail pix=q{queue_head}; for i=1:ser1 pix1=pix+neighbour(i,:); if pix1(1)>=1 && pix1(2)>=1 &&pix1(1)<=m && pix1(2)<=n if img(pix1(1),pix1(2))==0 img(pix1(1),pix1(2))=1; result(pix1(1),pix1(2))=1; q{queue_tail}=[pix1(1) pix1(2)]; queue_tail=queue_tail+1; end end end queue_head=queue_head+1; end figure(1) imshow(mat2gray(result)); title('提取之后的结果');
结果:
下面展示一种递归的算法:
clear all; %清理内存 close all; %关闭窗口 clc %清屏 %图像分割 Ii=imread('shape.bmp'); %读取彩色图像并转换为灰度图像 QuYuFenGe(Ii); %区域分割(8邻域区域生长)
function QuYuFenGe(Ii) figure,subplot(1,2,1),imshow(Ii),title('二值化图像'); %显示输入图像 %通过“鼠标点击+回车”,选取种子点(x0,y0) %规定:只允许在对象(白色区域)中选取一个种子点 x0=1; y0=1; while Ii(x0,y0) == 255 [y0,x0]=getpts; x0=uint32(x0); y0=uint32(y0); end [M,N]=size(Ii); %TODO: 初始化大小为M×N、像素值为0的输出图像Io Io=zeros(M,N); Io=QuYuShengZhang(x0,y0,Io,Ii); %对Io执行区域迭代生长 subplot(1,2,2),imshow(Io,[]),title('分割后图像'); %显示分割后图像
function Io=QuYuShengZhang(x0,y0,Io,Ii) [M,N]=size(Ii); for i=[-1,0,1]%TODO: 对于每个种子点(x0,y0),遍历它的每个8邻域像素(xn,yn) for j=[-1 0 1]%TODO %TODO: 计算xn, yn xn=x0+i; yn=y0+j; if (xn>0&&xn<=M && yn>0 && yn<=N &&Ii(x0,y0)==Ii(xn,yn) && Io(xn,yn)==0) %TODO: 如果(xn,yn)位于图像空间内,并且同时满足Ii(x0,y0)=Ii(xn,yn),Io(xn,yn)=0 Io(xn,yn)=255;%TODO: 区域生长 Io=QuYuShengZhang(xn,yn,Io,Ii); %将(xn,yn)作为新的种子点,重复此步骤 end end end