matlab利用K-Means图像压缩
应用K-Means算法来压缩图像
原理为:先对图像的每个像素运行K-Means算法,然后将每个像素映射为最近的质心。
应用K-Means算法来压缩图像代码
设置k值
,即将图像压缩为几色,设置最大迭代次数。
% 可以尝试修改如下的K值及最大迭代次数max_iters
K = input('请输入K值(2~16):');
max_iters = input('请输入最大迭代次数(10~50):');
% 加载图像文件
A = double(imread('img.jpg'));
A = A / 255; % 除以255将三原色的值转换为0~1之间
% 图像尺寸
img_size = size(A)
% 重新调整图像数据为Nx3矩阵,N为像素数目。每行有三列,分别为RGB三色
X = reshape(A, img_size(1) * img_size(2), 3);
% 随机设置初始质心
initial_centroids = initCentroids(X, K);
% 运行K-Means算法
%[centroids, ~] = runkMeans(X, initial_centroids, max_iters);
% Initialize values
[n , ~] = size(X);
K = size(initial_centroids, 1);
centroids = initial_centroids;
previous_centroids = centroids;
idx = zeros(n, 1);
% 迭代运行K-Means算法
for ii = 1 : max_iters
% 输出迭代次数
%fprintf('K-Means迭代次数:%d/%d...\n', ii, max_iters);
% 将数据集中的每一个样本分配给离它最近的质心
idx = EStep(X, centroids);
% 计算新质心
centroids = MStep(X, idx, K);
end
%% 图像压缩
% 查找最近的质心
idx = EStep(X, centroids);
% 压缩的实质是:将原始图像数据X用质心来表示
% 因此,将每个像素映射为质心颜色值
X_recovered = centroids(idx, :);
% 重新调整矩阵为适合的图像尺寸
X_recovered = reshape(X_recovered, img_size(1), img_size(2), 3);
% 显示原始图像
subplot(1, 2, 1);
imshow(A);
axis image;
title('原始图像');
% 显示压缩图像
subplot(1, 2, 2);
imshow(X_recovered);
axis image;
title(sprintf('压缩图像(%d色)', K));
% 保存压缩图像
imwrite(X_recovered, '4.jpg');
fprintf('\nK-Means运行完毕。\n\n');
图像显示:
如图是将原始图像压缩为四色,即为四个聚类中心。
计算图像压缩率
原始图像的分辨率为4000×2992,也就是N=4000×2992=11968000个像素,共需要24×11968000=287232000比特。压缩图像为4色,即为k等于4,
l
o
g
2
K
=
2
log_2K=2
log2K=2,则图像压缩后需
24
K
+
N
l
o
g
2
K
=
24
×
4
+
11968000
×
2
=
23936096
24K+Nlog_2K=24×4+11968000×2=23936096
24K+Nlog2K=24×4+11968000×2=23936096比特,压缩率为8.3%。
文件会有头部信息等其它信息,实际文件大小会较大,因此计算实际压缩率,原始图像文件实际占1847296字节,压缩图像文件占516096字节,实际压缩率约为27.9%。