K-Means和图片压缩

通俗的介绍这种压缩方式,就是将原来很多的颜色用少量的颜色去表示,这样就可以减小图片大小了。下面首先我先介绍下K-Means,当你了解了K-Means那么你也很容易的可以去理解图片压缩了,最后附上图片压缩的核心代码。

K-Means的核心思想

k-means的核心算法也就上面寥寥几句,下面将分三个部分来讲解:初始化簇中心、簇分配、簇中心移动。

初始化簇中心

随机取簇中心若是不幸,会出现局部最优的情况;想要打破这种情况,需要多次取值计算来解决这种情况。

代价函数

代码实现

J = zeros(100,1);
M = size(X,1);
min = inf;
for i = 1:100
    %随机取k个样本点作为簇中心
    randidx = randperm(M);
    initial_centroids = X(randidx(1:K),:);
    %将所得的中心点进行训练
    [centroids0, idx] = runkMeans(X, initial_centroids,10);
    for k = 1:M 
       J(i) = J(i) + sum((X(k,:) - centroids0(idx(M),:)).^2); 
    end
    %取最小代价为样本中心点
    if(min > J(i))
        centroids =centroids0;
    end
end

簇分配

将样本点分配到离它最近的簇中心下

tmp = zeros(K,1);
for i = 1:size(X,1)
    for j = 1:K
        tmp(j) = sum((X(i,:) - centroids(j,:)).^2);
    end
    [mins,index]=min(tmp);
    idx(i) = index;
end

簇中心移动

取当前簇中心下所有样本点的均值为下一个簇中心

for i = 1:m
    centroids(idx(i),:) = centroids(idx(i),:) + X(i,:);
end

for j = 1:K
    centroids(j,:) = centroids(j,:)/sum(idx == j);
end

图片压缩

%  加载图片
A = double(imread('dragonfly.jpg'));

% 特征缩减
A = A / 255; 

img_size = size(A);
X = reshape(A, img_size(1) * img_size(2), 3);
K = 16; 
max_iters = 10;

%开始训练模型
initial_centroids = kMeansInitCentroids(X, K);
[centroids, idx] = runkMeans(X, initial_centroids, max_iters);

%开始压缩图片
idx = findClosestCentroids(X, centroids);
X_recovered = centroids(idx,:);
X_recovered = reshape(X_recovered, img_size(1), img_size(2), 3);

%输出所压缩的图片
subplot(1, 2, 2);
imagesc(X_recovered)
posted @ 2017-11-19 20:13  学会思考の小R  阅读(1278)  评论(0编辑  收藏  举报