基于k-means的图像分割MATLAB程序

基于k-means的图像分割MATLAB程序,第1张

close all

clear

I_rgb = imread('color-cam4-f0.bmp') %读取文件数据

figure(1)

subplot(1,2,1)

imshow(I_rgb) %显示原图

title('原始图像')

%将彩色图像从RGB转化到lab彩色空间

C = makecform('srgb2lab') %设置转换格式

I_lab = applycform(I_rgb, C)

%进行K-mean聚类将图像分割成3个区域

ab = double(I_lab(:,:,2:3)) %取出lab空间的a分量和b分量

nrows = size(ab,1)

ncols = size(ab,2)

ab = reshape(ab,nrows*ncols,2)

nColors = 4 %分割的区域个数为

[cluster_idx cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean','Replicates',100) %重复聚类3次

pixel_labels = reshape(cluster_idx,nrows,ncols)

figure(1)

subplot(1,2,2)

imshow(pixel_labels,[]), title('聚类结果')

%显示分割后的各个区域

segmented_images = cell(1,nColors)

rgb_label = repmat(pixel_labels,[1 1 3])

for k = 1:nColors

color = I_rgb

color(rgb_label ~= k) = 0

segmented_images{k} = color

end

for i=1:nColors

figure(2),subplot(1,nColors,i)imshow(segmented_images{i}), title('分割结果')

end

function [mu,mask]=kmeans(ima,k)%k为指定类别数

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%

% kmeans image segmentation

%

% Input:

% ima: grey color image灰度图像

% k: Number of classes指定的图像中类别数目

% Output:

% mu: vector of class means 每个类的均值

% mask: clasification image mask分类后的图像掩膜(mask)

%

% Author: Jose Vicente Manjon Herrera

%Email: [email protected]

% Date: 27-08-2005

%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% check image

ima=double(ima)

copy=ima% make a copy

ima=ima(:) % vectorize ima将图像向量化,即一维化。

mi=min(ima) % deal with negative

ima=ima-mi+1% and zero values

s=length(ima)%获得图像像素个数

% create image histogram%创建图像直方图

m=max(ima)+1%最大像素值加1

h=zeros(1,m)%直方图,有m个bin

hc=zeros(1,m)%标号矩阵,每个像素点的值为该点所隶属的类别号

for i=1:s%s是图像象素个数,即考查每个像素

if(ima(i)>0) h(ima(i))=h(ima(i))+1end%直方图中对应bin加1

end

ind=find(h)%找到直方图中不为零的那些bin的序号。

hl=length(ind)%直方图中非零bin的个数

% initiate centroids

mu=(1:k)*m/(k+1)%k为指定的类别数,mu为不同类的分割点,相当于坐标轴上的整点

% start process

while(true)

oldmu=mu

% current classification

for i=1:hl

c=abs(ind(i)-mu)%就是相当于考察ind(i)在坐标轴上离哪个整点最近!注意mu总共就k个

cc=find(c==min(c))%cc保留距离ind(i)最近整点的序号,序号为1、2、3...k

hc(ind(i))=cc(1)

end

%recalculation of means 下面的程序用于计算每一类的均值位置

for i=1:k,

a=find(hc==i)

mu(i)=sum(a.*h(a))/sum(h(a))%h为直方图

end

if(mu==oldmu) breakend%循环结束条件

end

% calculate mask

s=size(copy)

mask=zeros(s)

mask1=mask%增加一个显示矩阵

size(mask1)

for i=1:s(1),

for j=1:s(2),

c=abs(copy(i,j)-mu)

a=find(c==min(c))

mask(i,j)=a(1)

end

end

mu=mu+mi-1 % recover real range

for i = 1 : k

p=find(mask==i)

mask1(p)=1/k*i

end

figure,imshow(mask1)

在聚类分析中,K-均值聚类算法(k-means algorithm)是无监督分类中的一种基本方法,其也称为C-均值算法,其基本思想是:通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。假设要把样本集分为c个类别,算法如下:(1)适当选择c个类的初始中心;(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类,(3)利用均值等方法更新该类的中心值;(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。下面介绍作者编写的一个分两类的程序,可以把其作为函数调用。%% function [samp1,samp2]=kmeans(samp)作为调用函数时去掉注释符samp=[11.1506 6.7222 2.3139 5.9018 11.0827 5.7459 13.2174 13.8243 4.8005 0.9370 12.3576]%样本集[l0 l]=size(samp)%%利用均值把样本分为两类,再将每类的均值作为聚类中心th0=mean(samp)n1=0n2=0c1=0.0c1=double(c1)c2=c1for i=1:lif samp(i)<th0c1=c1+samp(i)n1=n1+1elsec2=c2+samp(i)n2=n2+1endendc1=c1/n1c2=c2/n2%初始聚类中心t=0cl1=c1cl2=c2c11=c1c22=c2%聚类中心while t==0samp1=zeros(1,l)samp2=samp1n1=1n2=1for i=1:lif abs(samp(i)-c11)<abs(samp(i)-c22)samp1(n1)=samp(i)cl1=cl1+samp(i)n1=n1+1c11=cl1/n1elsesamp2(n2)=samp(i)cl2=cl2+samp(i)n2=n2+1c22=cl2/n2endendif c11==c1 &&c22==c2t=1endcl1=c11cl2=c22c1=c11c2=c22end %samp1,samp2为聚类的结果。初始中心值这里采用均值的办法,也可以根据问题的性质,用经验的方法来确定,或者将样本集随机分成c类,计算每类的均值。k-均值算法需要事先知道分类的数量,这是其不足之处。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11144792.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存