通俗的介紹這種壓縮方式,就是將原來不少的顏色用少許的顏色去表示,這樣就能夠減少圖片大小了。下面首先我先介紹下K-Means,當你瞭解了K-Means那麼你也很容易的能夠去理解圖片壓縮了,最後附上圖片壓縮的核心代碼。算法
k-means的核心算法也就上面寥寥幾句,下面將分三個部分來說解:初始化簇中心、簇分配、簇中心移動。函數
隨機取簇中心如果不幸,會出現局部最優的狀況;想要打破這種狀況,須要屢次取值計算來解決這種狀況。code
代價函數
blog
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
取當前簇中心下全部樣本點的均值爲下一個簇中心it
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)