1 原理
FCM(Fuzzy C-Means)聚类图像分割原理主要基于模糊聚类理论,将图像中的像素点按照其灰度值、颜色或纹理等特征进行模糊划分,使得图像中具有相似特性的区域能够被聚类成同一类,进而实现图像的分割。以下是FCM聚类图像分割原理的详细解释,包括公式和步骤:
1.1 FCM聚类原理
FCM聚类算法是一种基于模糊理论的聚类算法,与传统的硬聚类(如K-means)不同,FCM允许一个像素点属于多个类别,每个像素点对每个类别的隶属度用一个介于0和1之间的数值来表示。
1.2 FCM目标函数
FCM算法的目标是最小化均方差函数,该函数描述了所有像素点与其所属聚类中心的距离的平方和。目标函数的公式如下:
其中:
- n是像素点的总数。
- c是预设的聚类数目。
- 是第 i个像素点对第 j 个聚类的隶属度,且 。
- m 是模糊指数,通常是一个大于1的实数,用于控制隶属度的模糊程度。
- 是第 i个像素点的特征向量(如灰度值、颜色等)。
- 是第 j个聚类的中心向量。
1.3 FCM聚类流程
FCM聚类算法的流程大致如下:
- 初始化:设定目标函数的精度、模糊指数 m、算法的最大迭代次数等参数,并随机初始化隶属度矩阵U。
- 计算聚类中心 :根据当前的隶属度矩阵 U,计算每个聚类的中心向量 。
- 更新隶属度矩阵 :根据新的聚类中心向量 ,更新隶属度矩阵 U。
- 迭代:重复步骤2和步骤3,直到满足迭代终止条件(如达到最大迭代次数或目标函数的值小于预设的精度)。
- 输出结果 :当迭代终止时,输出最终的隶属度矩阵 U和聚类中心向量 。
2 代码
Matlab
%%
function [segmented_image, U, centers] = fuzzy_c_means_clustering(image, num_clusters, max_iter, m, error_tolerance)
% image: 输入的灰度图像,应该是一个二维数组
% num_clusters: 聚类的数量
% max_iter: 最大迭代次数
% m: 模糊加权指数,通常取值在[1.5, 2.5]之间
% error_tolerance: 收敛的误差容忍度
% 初始化参数
[rows, cols] = size(image);
data = double(reshape(image, rows*cols, 1)); % 将图像转换为一维数组
num_pixels = rows*cols;
% 初始化隶属度矩阵U,随机值在[0, 1]之间,并归一化每一行使其和为1
U = rand(num_pixels, num_clusters);
for i = 1:num_pixels
U(i,:) = U(i,:) / sum(U(i,:));
end
% 初始化聚类中心centers
centers = rand(num_clusters, 1) * max(data);
% FCM算法迭代
for iter = 1:max_iter
% 计算新的聚类中心
for j = 1:num_clusters
weights = U(:,j).^m; % 计算权重
centers(j) = sum(weights .* data) / sum(weights); % 更新聚类中心
end
% 计算新的隶属度矩阵U
old_U = U;
for i = 1:num_pixels
distances = sum((data(i,:) - centers).^2, 2); % 计算每个像素到聚类中心的距离
powers = 1 ./ (distances + eps).^(1/(m-1)); % 避免除以零,并计算距离的幂
U(i,:) = powers ./ sum(powers); % 更新隶属度矩阵
end
% 检查收敛性
if norm(U - old_U, 'fro') < error_tolerance
break;
end
end
% 将分割结果重新整形为图像
segmented_image = reshape(max(U, [], 2), rows, cols); % 取隶属度最大的类别作为分割结果
segmented_image = uint8(segmented_image * 255); % 转换为8位无符号整数
end
% 读取图像
image = imread('test.jpg');
image = rgb2gray(image); % 如果图像是彩色的,则转换为灰度图像
% 设置FCM参数
num_clusters = 3; % 假设我们想要分割成3个类别
max_iter = 2;
m = 2;
error_tolerance = 1e-5;
% 执行FCM聚类
[segmented_image, U, centers] = fuzzy_c_means_clustering(image, num_clusters, max_iter, m, error_tolerance);
% 显示原始图像和分割后的图像
figure;
subplot(1, 2, 1);
imshow(image);
title('原始图像');
subplot(1, 2, 2);
imshow(segmented_image, []); % 显示分割后的图像,可能需要调整颜色映射
title('FCM聚类分割后的图像');
%
% % 如果需要,可以显示聚类中心或隶属度矩阵U
% disp('聚类中心:');
% disp(centers);
% disp('隶属度矩阵U:');
% disp(U);
3 运行结果
图1 FCM聚类分割对比图
从图1中可以看出分割效果底下,这是迭代10次的效果,在迭代1000次后效果会改善很多。