kmeans--第一个matlab算法

来源:互联网 发布:公积金管理系统uc矩阵 编辑:程序博客网 时间:2024/06/10 08:23

%k均值算法
imMatrix = imread('../pic/qiushuzhen.jpg'); % 404x500x3
imMatrix = imMatrix(150:350,150:350,1:end);


KM = 32; %最终聚类的大小
%图像的大小
rgbSize = size(imMatrix); %数组下标从1开始
%imshow(imMatrix); %显示图片
%imMatrix(1,1,1:end)
%for i=1:1:rgbSize(1)
%    for j=1:1:rgbSize(2)
%        imMatrix(i,j,1) = 0; %为了方便显示
%        imMatrix(i,j,2) = 0;
%    end
%end


%算法开始
%原始的切分点(转置)
repeat_max_count = 50;
sp = [zeros(1,KM);zeros(1,KM);linspace(1,255,KM)]';
sp_res = cell(repeat_max_count);
sp_res{1} = sp;
all_sp_dis = 100000000;
repeat_count = 1;
while 1
    sp_point_sum = zeros(KM,3); %收集到的点的各个维度的像素和
    sp_sum = zeros(KM,1); %收集到的像素点在切分点之和
    sp_cnt = zeros(KM,1); %收集到的像素点在切分点的个数
    %im2sp imMatrix归属于哪个切分点(数组下标)
    %im2sp=zeros(rgbSize(1), rgbSize(2));
    for i=1:1:rgbSize(1)
        for j=1:1:rgbSize(2)
            dis = 100000;
            selectp = 1;
            for k=1:1:KM %选出最近的那个点
                ss=sp(k,1:end,1:end)';
                tp = [imMatrix(i,j,1) imMatrix(i,j,2) imMatrix(i,j,3)]';
                dis_p = ss-double(tp);  
                dis2 = norm(dis_p,3);
                if dis2 < dis
                    dis = dis2;
                    selectp = k;
                end
            end
            tt = sp_point_sum(selectp,1:end);
            tp = double([imMatrix(i,j,1) imMatrix(i,j,2) imMatrix(i,j,3)]);
            sp_point_sum(selectp,1:end) = tt + tp;
            sp_sum = sp_sum + dis;
            sp_cnt(selectp) = sp_cnt(selectp) + 1;
        end
    end
    sp_new = zeros(KM,3);
    sp_all_change = 0; %两次计算的原始点之间的变化率,判断结束的条件
    for ii=1:1:KM
        if sp_cnt(ii) == 0
            sp_new(ii) = sp(ii);
        else
            sp_new(ii,1:end) = sp_point_sum(ii,1:end)/sp_cnt(ii);
            sp_all_change = sp_all_change + norm(sp_new(1:end)-sp(1:end), 3);
        end
    end
    
    repeat_count = repeat_count + 1
    if repeat_count >= repeat_max_count
        break
    end
    sp = sp_new;
    %sp_res = [sp_res;sp];
    sp_res{repeat_count} = sp;
    if all_sp_dis - sp_all_change < 1
        break
    end
    all_sp_dis = sp_all_change;
    %length(x1)-length(unique(x1))
end


y_count = 5;
x_count = double(int8((repeat_count + y_count - 1 + 1) / y_count));
subplot(x_count,y_count,1);
imshow(imMatrix);
for ii=1:1:repeat_count
    imMatrixTmp = imMatrix;
    ssp = cell2mat(sp_res(ii));
    for i=1:1:rgbSize(1)
        for j=1:1:rgbSize(2)
            dis = 100000;
            selectp = 1;
            for k=1:1:KM %选出最近的那个点
                ss=ssp(k,1:end,1:end)';
                tp = [imMatrixTmp(i,j,1) imMatrixTmp(i,j,2) imMatrixTmp(i,j,3)]';
                dis_p = ss-double(tp);  
                dis2 = norm(dis_p,3);
                if dis2 < dis
                    dis = dis2;
                    selectp = k;
                end
            end
            imMatrixTmp(i,j,1:end) = uint8(ssp(selectp,1:end));
        end
    end
    [x_count y_count ii]
    subplot(x_count,y_count,ii+1);
    imshow(imMatrixTmp);
end


0 0