这一篇是补充前一篇的。相比前一篇的第二种实现方法,这里使用了均值、标准差随迭代更新的策略,且根据区域的性质,对三通道取不同的权值。修正后的程序为:
clear all;close all;clc;
img=imread('parrot.png');
subplot(3,1,1),
imshow(img);
[m,n,~]=size(img);
seeds=[400,200,1;230,600,2;440,670,3]; %第3列为label
labelNum=3;
newSeeds=seeds;
hold on;
plot(seeds(:,2)',seeds(:,1)','gs','linewidth',1);
title('原始图像及种子位置');
flag=1;
ycc=double(rgb2ycbcr(img));
Y=ycc(:,:,1);
Cb=ycc(:,:,2);
Cr=ycc(:,:,3);
img=double(img);
R=img(:,:,1);
G=img(:,:,2);
B=img(:,:,3);
mask=zeros(m,n);
for i=1:size(seeds,1)
mask(seeds(i,1),seeds(i,2))=1;
end
avgs=zeros(labelNum,3);%初始均值
stds=repmat([30,10,10],[size(seeds,1),1]); %初始标准差
w=[5,5,5;3,2.2,2.8;3,3,3.5]; %各区域三通道权重
while(flag)
temp=[];
for i=1:labelNum
index=find(seeds(:,3)==i);
selected=seeds(index,1:2);
indexS=m*(selected(:,2)-1)+selected(:,1);
yS=Y(indexS);
CbS=Cb(indexS);
CrS=Cr(indexS);
rgbSamp=[yS,CbS,CrS];
avgs(i,:)=sum(rgbSamp,1)/length(index);
if size(rgbSamp,1)>1
stds(i,:)=std(rgbSamp,1);
end
end
stds=max(5,stds);
for i=1:size(newSeeds,1)
rowS=newSeeds(i,1);
colS=newSeeds(i,2);
label=newSeeds(i,3);
rlow=max(1,rowS-1);
rhigh=min(m,rowS+1);
clow=max(1,colS-1);
chigh=min(n,colS+1);
for row=rlow:rhigh
for col=clow:chigh
if mask(row,col)==1 %已经添加过的排除掉
continue;
end
diffycc=reshape(ycc(row,col,:),1,size(ycc,3))-avgs(label,:);
judge=abs(diffycc)<w(label,:).*stds(label,:);
if sum(judge)==3 % R、G、B、Y均在3倍均方根范围内
temp=[temp;row,col,label];
mask(row,col)=1;
end
end
end
end
newSeeds=temp;
seeds=[seeds;newSeeds];
if isempty(temp)
flag=0;
end
end
imlabel=zeros(m,n);
for i=1:size(seeds,1)
imlabel(seeds(i,1),seeds(i,2))=seeds(i,3);
end
mask=cat(3,mask,mask,mask);
sgImg=mask.*img;
imlabel=0.5*mat2gray(imlabel)+0.5;
subplot(3,1,2);
imshow(uint8(sgImg));
title('分割结果');
subplot(3,1,3);
imshow(imlabel);
title('种子点生长获得的掩模');
分割结果:
可以看到,这种方法比第一种方法获得了更好的分割效果。