使用K-means算法聚类灰度图

版权声明:分享才能获得最大的价值 https://blog.csdn.net/qq_32252957/article/details/83796140

github数据集: 智能算法的课件和参考资料以及实验代码

我们可以用k-means算法将灰度图分成N个梯度

我们知道,一般的彩色图像指的是在RGB颜色空间下的图像,这样的图像三个通道分别是R(red)G(green)B(blue)。而灰度图指的是单通道的,将三通道的图像转为单通道常用方法有YUV法和平均法。

如何将一幅彩色图像转换为灰度图呢?根据人眼对红绿蓝三色的敏感程度,可以使用以下方式进行转换:

         Gray = R*0.299+G*0.587+B*0.114

这也是最常用的一种转换,另外还有一种常用的转换叫平均值法,即取去红绿蓝三色的平均值为灰度:

         Gray=(R+G+B)/3;

下面使用K-means算法将lenna256.bmp图像聚类成N类来处理:

close all
clear all
clc
I=imread('lenna256.bmp'); % 从指定的文件名(这里是相对目录,即当前程序所在目录)读取图像
I=im2double(I); % 把灰度图像的数据类型转换成双精度浮点数类型
J=zeros(size(I)); % 256*256 8位的灰度图
N=4; % 聚类成N类
[m,n]=size(I); % m=256,n=256
center=zeros(1,N);
% 下面初始化簇中心,有N个簇中心
for i=1:N
	mrand1=randi(m);
	nrand1=randi(n);
	center(1,i)=I(mrand1,nrand1);
end
label=zeros(m,n);
s=zeros(1,N);
num=zeros(1,N);
newcenter=zeros(1,N);
th=0.01;
while 1
    distance=zeros(1,N);
    for i=1:m
        for j=1:n
            for x=1:N
                distance(x)=abs(I(i,j)-center(1,x));% 一维距离,直接相差取绝对值
            end
            [~,temp]=min(distance);
            label(i,j)=temp; % 第i行j列的样本属于temp类别
        end
    end
    for i=1:m
        for j=1:n
        	% 求第i,j个样本到N个簇中心的平均距离
            for x=1:N
                if(label(i,j)==x)
                    s(1,x)=s(1,x)+I(i,j);
                    num(1,x)=num(1,x)+1; % 计算每个类别的样本数量
                end
            end
        end
    end
    % 计算新的N个簇的中心
    for x=1:N
        newcenter(1,x)=s(1,x)/num(1,x);
    end
    % 当簇中心变化很小时收敛
    if(abs(min(newcenter)-min(center))<th)
        break;
    else
        center=newcenter;
    end
end
for i=1:m
        for j=1:n
            for x=1:N
                if(label(i,j)==x)
                    J(i,j)=center(x)*255; % 将样本划分到所属类别中
                end
            end
        end
    end
figure,
subplot(1,2,1),imshow(I); % 将图像窗口分成1行2列,并在第一个子窗口显示图像img
subplot(1,2,2),imshow(uint8(J)); % 同上,只不过换成在第二个子窗口显示img
% 注意:
% subplot(1,2,2),imshow(J); 会得到白色图像
% 可以使用subplot(1,2,2),imshow(J/255);

注意imshow的使用:

matlab中显示图像的语句是:

                                                         imshow(img)
                                                   imshow(img,[low high])
其中,[low high]用于指定图像显示的灰度范围,图像中灰度值等于或低于low的都将用显示为黑色,灰度值等于或大于high的都显示为白色。如果你用空矩阵[]来代替 [low high], imshow 函数将使用 [min(img(:))max(img(:))]作为第二个参数。
在某些需要保证精度的场合,我们可能会将图像数据保存为double型,此时运行 imshow(img)会得到一张空白的图。
这是因为imshow()显示图像时对double型是认为在0-1范围内,即大于1时都是显示为白色,而imshow()显示uint8型时是0-255范围。

解决办法就是调整图像的数据区间或调整显示的区间:
方法一: imshow(img/256);    -----------将图像矩阵转化到0-1之间。

方法二: imshow(I,[]);       -----------将显示区间转换到 min(img(:)) 到max(img(:))之间

分成四类结果如下:

猜你喜欢

转载自blog.csdn.net/qq_32252957/article/details/83796140