基于matlab的FCM聚类图像分割

1 原理

FCM(Fuzzy C-Means)聚类图像分割原理主要基于模糊聚类理论,将图像中的像素点按照其灰度值、颜色或纹理等特征进行模糊划分,使得图像中具有相似特性的区域能够被聚类成同一类,进而实现图像的分割。以下是FCM聚类图像分割原理的详细解释,包括公式和步骤:

1.1 FCM聚类原理

FCM聚类算法是一种基于模糊理论的聚类算法,与传统的硬聚类(如K-means)不同,FCM允许一个像素点属于多个类别,每个像素点对每个类别的隶属度用一个介于0和1之间的数值来表示。

1.2  FCM目标函数

FCM算法的目标是最小化均方差函数,该函数描述了所有像素点与其所属聚类中心的距离的平方和。目标函数的公式如下:

eq?J%20%3D%20%5Csum_%7Bi%3D1%7D%7Bn%7D%20%5Csum_%7Bj%3D1%7D%7Bc%7D%20u_%7Bij%7D%7Bm%7D%20%7C%7C%20x_%7Bi%7D%20-%20v_%7Bj%7D%20%7C%7C%7B2%7D

其中:

  • n是像素点的总数。
  • c是预设的聚类数目。
  • eq?u_%7Bij%7D是第 i个像素点对第 j 个聚类的隶属度,且 eq?u_%7Bij%7D%20%5Cin%20%5B0%2C%201%5D
  • m 是模糊指数,通常是一个大于1的实数,用于控制隶属度的模糊程度。
  • eq?x_%7Bi%7D是第 i个像素点的特征向量(如灰度值、颜色等)。
  • eq?v_%7Bj%7D是第 j个聚类的中心向量。

1.3 FCM聚类流程

FCM聚类算法的流程大致如下:

  1. 初始化:设定目标函数的精度、模糊指数 m、算法的最大迭代次数等参数,并随机初始化隶属度矩阵U。
  2. 计算聚类中心:根据当前的隶属度矩阵 U,计算每个聚类的中心向量 eq?v_%7Bj%7D
  3. 更新隶属度矩阵:根据新的聚类中心向量 eq?v_%7Bj%7D,更新隶属度矩阵 U。
  4. 迭代:重复步骤2和步骤3,直到满足迭代终止条件(如达到最大迭代次数或目标函数的值小于预设的精度)。
  5. 输出结果:当迭代终止时,输出最终的隶属度矩阵 U和聚类中心向量 eq?v_%7Bj%7D

2 代码

%% 
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 运行结果

0f614e5ab55e479d9ba349dd605f826a.jpeg

图1 FCM聚类分割对比图

        从图1中可以看出分割效果底下,这是迭代10次的效果,在迭代1000次后效果会改善很多。

 

 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值