1 原理
K-means聚类算法在图像分割中的应用是基于一种无监督的学习方法,它将图像中的像素点或特征区域划分为K个不同的簇或类别。以下是K-means聚类算法用于图像分割的原理,包括步骤和公式:
1.1 原理概述
- 选择簇的数量(K):
- 首先,用户需要指定要将图像数据分成多少个簇(即K的值)。
- 初始化聚类中心:
- 随机选择K个像素点作为初始聚类中心。
- 分配数据点到最近的聚类中心:
- 对于图像中的每个像素点,计算其与每个聚类中心的距离(如欧氏距离),并将其分配给距离最近的聚类中心所在的簇。
- 更新聚类中心:
- 对于每个簇,计算该簇中所有像素点的平均值(或质心),并将这个平均值作为新的聚类中心。
- 重复迭代:
- 重复步骤3和步骤4,直到聚类中心不再发生显著变化或达到预定的迭代次数。
1.2 公式表示
- 距离计算(以欧氏距离为例):
设为图像中的一个像素点(或特征向量),
为第j个聚类中心,则像素点
到聚类中心
的欧氏距离计算公式为:
其中,D是像素点或特征向量的维度。
- 聚类中心的更新:
- 对于每个簇
,其新的聚类中心
计算公式为:
- 对于每个簇
- 其中,
是簇
中像素点的数量。
1.3 步骤总结
- 初始化:选择K个初始聚类中心。
- 分配:计算每个像素点到聚类中心的距离,并将其分配给最近的聚类中心。
- 更新:重新计算每个簇的聚类中心。
- 迭代:重复步骤2和步骤3,直到聚类中心不再变化或达到预设的迭代次数。
1.4 注意事项
- K-means算法对初始聚类中心的选择敏感,因此可能多次运行算法并选择最佳结果。
- SSE(Sum of Squared Errors)是衡量聚类效果的一个指标,其值越小表示聚类结果越紧密。
- 图像分割中的K-means算法通常是在图像的特征空间(如颜色空间、纹理空间等)上进行的,而不是直接在像素值上进行。这有助于提高算法的鲁棒性和效率。
2 代码
%% 基于聚类的分割 (使用K-means聚类)
figure('Position', [100 100 1200 400]);
% 读取图像并转换为双精度
I3 = imread('test.jpg');
I3 = rgb2gray(I3);
subplot(1,3,1);imshow(I3);
title('origin Image');
% 读取图像并转换为双精度
I4 = imread('test.jpg');
I_double = im2double(I4);
% 将图像数据重塑为二维数组,其中每一列是一个像素
data = reshape(I_double, [], 3);
% 使用K-means聚类
[cluster_idx, cluster_center] = kmeans(data, 3); % 假设我们想要3个聚类
% 将聚类结果重塑为图像大小
segmented_image = reshape(cluster_idx, size(I4, 1), size(I4, 2));
% 显示结果(可能需要为每个聚类分配一个颜色)
segmented_image_colored = label2rgb(segmented_image, 'jet', 'k', 'shuffle');
subplot(1,3,2);imshow(segmented_image_colored);
title('three colors Image using K-means Clustering');
% 读取图像并转换为灰度
I5 = imread('test.jpg');
I_gray = rgb2gray(I5);
I_double = im2double(I_gray);
% 将图像数据重塑为二维数组
data = I_double(:);
% 使用两个中心的K-means聚类
[cluster_idx, cluster_center] = kmeans(data, 2);
% 将聚类结果重塑为图像大小
segmented_image = reshape(cluster_idx, size(I_gray));
% 为每个聚类分配一个颜色(在这种情况下,0为黑色,1为白色)
segmented_image_bw = ind2rgb(segmented_image, [0 0 0; 1 1 1]);
% 显示结果
subplot(1,3,3);imshow(segmented_image_bw);
title('Black and White Image using K-means Clustering');
3 运行结果
图1 图像分割对比图