基于区域的图像分割matlab

1、区域的分离和聚合

步骤:

1)根据条件判断是否将当前图像块进行四分,开始时是整张图像,(进行的是平均四分,所以图像大小需要是2的幂次),然后是小图像块,进行不断划分,知道满足停止条件。

2)对相邻小块像素进行合并,imreconstruct用于此,知道不能合并

qtdecomp函数是用来分解图像的,(四叉树分解),

Z=qtdecomp(f,@split_test,parameters),

将f传入到函数split_test中,split这个函数其实就是起到调用predicate函数的作用,predicate函数是判断是否需要分的条件函数。

function v=split_test(B,mindim,fun)
 K=size(B,3);%B就是qtdecomp函数传过来的,代表当前size(B,3)返回的是B的层数,就是B是几维的,这里实际上就是有几个B这样大小的图像块
 %这句代码的意思是从qtdecomp函数传过来的B,是当前分解成的K块的m*m的图像块,K表示有多少个这样大小的图像块
 v(1:K)=false;
 for I=1:K
     quadregion=B(:,:,I);
     if size(quadregion,1)<=mindim%如果分的块的大小小于mindim就直接结束
         v(I)=false;
         continue
     end
     flag=feval(fun,quadregion);%quadregion是fun函数的参数,fun(quadregion)
     if flag%如果flag是1,代表需要再分
         v(I)=true;%这里就相当于split_test是起一个调用predicate的作用,返回的就是ppredicate的值
     end
 end
end



function flag=predicate(region)%和图像标准差和均值有关
sd=std2(region);
m=mean2(region);
flag=(sd>22)&(m>5)&(m<255);%参数自己根据实际情况调整
end

主函数

clc
clear

f=imread('E:\桌面\数字图像matlab\DIP3E_CH10_Original_Images\DIP3E_Original_Images_CH10\Fig1053(a)(cygnusloop_Xray_original).tif');

g=splitmerge(f,8,@predicate);
figure,imshow(g)

splitmerge就是主要实现区域分离和合并的函数

function g=splitmerge(f,mindim,fun)%f是待分割的原图,mindim是定义分解中所允许的最小的块,必须是2的正整数次幂
 Q=2^nextpow2(max(size(f)));
 [M,N]=size(f);
 f=padarray(f,[Q-M,Q-N],'post');%:填充图像或填充数组。f是输入图像,输出是填充后的图像,先将图像填充到2的幂次以使后面的分解可行
 %然后是填充的行数和列数,post:表示在每一维的最后一个元素后填充,B = padarray(A,padsize,padval,direction)
 %不含padval就用0填充,Q代表填充后图像的大小。
 S=qtdecomp(f,@split_test,mindim,fun);%f传给split_test,qtdecomp divides a square image into four
% equal-sized square blocks, and then tests each block to see if it
% meets some criterion of homogeneity. If a block meets the criterion,
% it is not divided any further. If it does not meet the criterion,
% it is subdivided again into four blocks, and the test criterion is
% applied to those blocks. This process is repeated iteratively until
% each block meets the criterion. The result can have blocks of several
% different sizes.S是包含四叉树结构的稀疏矩阵,存储的值是块的大小及坐标,以稀疏矩阵形式存储
 Lmax=full(max(S(:)));%将以稀疏矩阵存储形式存储的矩阵变换成以普通矩阵(full matrix)形式存储,full,sparse只是存储形式的不同
 g=zeros(size(f));
 MARKER=zeros(size(f));
 
 for k=1:Lmax
     [vals,r,c]=qtgetblk(f,S,k);%vals是一个数组,包含f的四叉树分解中大小为k*k的块的值,是一个k*k*个数的矩阵,
     %个数是指S中有多少个这样大小的块,f是被四叉树分的原图像,r,c是对应的左上角块的坐标如2*2块,代表的是左上角开始块的坐标
     
     if ~isempty(vals)
         for I=1:length(r)
             xlow=r(I);
             ylow=c(I);
             xhigh=xlow+k-1;
             yhigh=ylow+k-1;
             region=f(xlow:xhigh,ylow:yhigh);%找到对应的区域
             flag=feval(fun,region);%evaluates the function handle, fhandle,using arguments x1 through xn.执行函数fun,region是参数
             if flag%如果返回的是1,则进行标记
                 g(xlow:xhigh,ylow:yhigh)=1;%然后将对应的区域置1
                 MARKER(xlow,ylow)=1;%MARKER矩阵对应的左上角坐标置1
             end
         end
     end
 end
 
 g=bwlabel(imreconstruct(MARKER,g));%imreconstruct默认2D图像8连通,这个函数就是起合的作用
 g=g(1:M,1:N);%返回原图像的大小
end

Matlab写的区域生长图像分割程序。 %区域生长算法:region function LabelImage=region(image,seed,Threshold,maxv) %image:输入图像 %seed:种子点坐标堆栈 %threshold:用邻域近似生长规则的阈值 %maxv:所有生长的像素的范围小于maxv % LabelImage:输出的标记图像,其中每个像素所述区域标记为rn [seedNum,tem]=size(seed);%seedNum为种子个数 [Width,Height]=size(image); LabelImage=zeros(Width,Height); rn=0;%区域标记号码 for i=1:seedNum %从没有被标记的种子点开始进行生长 if LabelImage(seed(i,1),seed(i,2))==0 rn=rn+1;% %对当前生长区域赋标号值 LabelImage(seed(i,1),seed(i,2))=rn; % end stack(1,1)=seed(i,1);%将种子点压入堆栈(堆栈用来在生长过程中的数据坐标) stack(1,2)=seed(i,2); Start=1;%定义堆栈起点和终点 End=1; while(Start<=End) %当前种子点坐标 CurrX=stack(Start,1); CurrY=stack(Start,2); %对当前点的8邻域进行遍历 for m=-1:1 for n=-1:1 % %判断像素(CurrX,CurrY)是否在图像内部 % rule1=(CurrX+m)=1&(CurrY+n)=1; % %判断像素(CurrX,CurrY)是否已经处理过 % rule2=LabelImage(CurrX+m,CurrY+n)==0; % %判断生长条件是否满足 % rule3=abs(double(image(CurrX,CurrY))-double(image(CurrX+m,CurrY+n)))<Threshold; % %条件组合 % rules=rule1&rule2&rule3; if (CurrX+m)=1&(CurrY+n)=1&LabelImage(CurrX+m,CurrY+n)==0&abs(double(image(CurrX,CurrY))-double(image(CurrX+m,CurrY+n)))<=Threshold&image(CurrX+m,CurrY+n)0 %堆栈的尾部指针后移一位 End=End+1; %像素(CurrX+m,CurrY+n)压入堆栈 stack(End,1)=CurrX+m; stack(End,2)=CurrY+n; %把像素(CurrX,CurrY)设置成逻辑1 LabelImage(CurrX+m,CurrY+n)=rn; end end end %堆栈的尾部指针后移一位 Start=Start+1; end end end
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值