图像分割之k-means聚类分割

news2024/11/27 10:33:58

文章目录

    • k-means聚类原理
    • k-means基本思路
    • 聚类效果评估
    • k-means聚类算法流程
    • MATLAB实现
    • 测试结果
    • 参考文献

k-means聚类原理

k-means聚类是一种无监督学习的聚类算法,它的目的是将数据集中的样本划分成若干个类别,使得同一类别内的样本相似度高,而不同类别之间的样本相似度低。其目标是将数据点划分为k个类簇,找到每个簇的中心并使其度量最小化。
此外,K-means算法有一些优点,如简单易懂、计算速度快,适合处理大数据集。但它也有一些缺点,比如需要预先指定簇的数量K,对初始聚类中心的选择敏感,可能收敛到局部最优而非全局最优解,对于非凸数据集和噪声数据敏感。
在实际应用中,K-means算法广泛应用于市场细分、图像分割、社交网络分析等领域。本文主要将其应用于图像分割领域。

k-means基本思路

通过计算相似度(默认欧氏距离),将相似度大的样本聚集到同一个类别,k表示聚成k个类别,means表示每个类别的聚类中心点是通过簇中所有样本点的均值得到。
在这里插入图片描述

聚类效果评估

聚类的效果可采用误差平方和SSE进行评价,SSE值越小,表示数据点越接近它们的中心点,聚类效果越好。
在这里插入图片描述

k-means聚类算法流程

下面是K-Means聚类算法的分析流程,步骤如下:

第一步,确定K值,即将数据集聚集成K个类簇或小组。
第二步,从数据集中随机选择K个数据点作为质心(Centroid)或数据中心。
第三步,分别计算每个点到每个质心之间的距离,并将每个点划分到离最近质心的小组,跟定了那个质心。
第四步,当每个质心都聚集了一些点后,重新定义算法选出新的质心。
第五步,比较新的质心和老的质心,如果新质心和老质心之间的距离小于某一个阈值,则表示重新计算的质心位置变化不大,收敛稳定,则认为聚类已经达到了期望的结果,算法终止。
第六步,如果新的质心和老的质心变化很大,即距离大于阈值,则继续迭代执行第三步到第五步,直到算法终止。

对于图像分割任务,需要在第一步之前将图像reshape为m*n行、p列的矩阵,这样每一行就是一个p维数据点。通过以上聚类算法,得到最终的聚类结果,最后再将结果reshape为原始图像的大小即可。

MATLAB实现

MATLAB自带函数

kmeans函数的说明如下:

idx = kmeans(X,k) 执行 k 均值聚类,以将 n×p 数据矩阵 X 的观测值划分为 k个聚类,并返回包含每个观测值的簇索引的 n×1 向量 (idx)。X 的行对应于点,列对应于变量。

根据上面的kmeans函数的说明,我们需要将图像矩阵reshape一下,然后再调用该函数,最后再reshape回来,下面是测试的主要代码:

[m,n,p]=size(img)              %m,n为所求,p=3为通道数
% 将图像进行RGB——3通道分解
% org(:, :, 1)......分别代表rgb通道
A = reshape(img(:, :, 1), m*n, 1);   
B = reshape(img(:, :, 2), m*n, 1);
C = reshape(img(:, :, 3), m*n, 1);
data = [A B C];  % r g b分量组成样本的特征,每个样本有三个属性值,共width*height个样本

% kmeans第一个参数: N*P的数据矩阵,N为数据个数,P为单个数据维度
res = kmeans(double(data), k);        
result = reshape(res, m, n);  %转化为图片形式

MATLAB实现

根据上述算法流程,使用matlab编写如下代码,其中设置强制截断的迭代次数,并添加了迭代过程展示。
my_kmeans函数:

function [C, label, J] = my_kmeans(data, k, is_gpu, is_show) 
%% 语法 :
% [C, label, J] = my_kmeans(data, k, is_gpu, is_show) 
%% 说明:
% data  为输入图像
% k  为聚类的k个数据中心
% is_gpu  是否启用gpu加速
% is_show  参数决定是否显示聚类过程
% ----------------------------------------
% return label  为返回的聚类结果
% return C  聚类中心
% return J  每次迭代的误差
%%
if nargin >= 3
    is_gpu = 1;
else
    is_gpu = 0;
end
if nargin == 4
    is_show = 1;
else
    is_show = 0;
end
%%
% data可以为一维数据
m = size(data, 1);
n = size(data, 2);
p = size(data, 3);
% [m, n, p] = size(I); %图片的大小m*n,p代表RGB三层
X = reshape(double(data), m*n, p);
if is_gpu
    X = gpuArray(X);
end
rng('default');
C = X(randperm(m*n, k), :);%随机选k个聚类中心

J = [];
J_prev = inf; 
tol = 1e-1; %容忍度tol,inf为无穷大
iter = 0; 
rand_c = rand(k,3)*255;
rand_c = uint8(rand_c);
while true
    iter = iter + 1;
    dist = sum(X.^2, 2)*ones(1, k) + (sum(C.^2, 2)*ones(1, m*n))' - 2*X*C'; %计算各个点到K个聚类中心的距离
    [~,label] = min(dist, [], 2) ;  %label记录最小值的行数
    for i = 1:k
       C(i, :) = mean(X(label == i , :)); %取新的k个聚类中心
    end
    J_cur = sum(sum((X - C(label, :)).^2, 2)); %距离之和
    J = [J, J_cur];
    fprintf('#iteration: %03d, objective norm diff: %f\n', iter, norm(J_cur-J_prev, 'fro'));
    if norm(J_cur-J_prev, 'fro') < tol   % A和A‘的积的对角线和的平方根,即sqrt(sum(diag(A'*A))),本次与上次距离之差
        break;
    end
    if (iter==100)  %设置强制截断的迭代次数
        break;
    end
    J_prev = J_cur;
    if is_show
        % 录制gif
        rand_c = uint8(C);
        temp = uint8(label);
        temp = rand_c(temp,:);
        sg=reshape(temp,m,n, []);
        imshow(mat2gray(sg));
        F=getframe(gcf);
        data=frame2im(F);
        [data,map]=rgb2ind(data,256);
        if iter == 1
            imwrite(data,map,'test.gif','gif','Loopcount',inf,'DelayTime',0.2);
        else
            imwrite(data,map,'test.gif','gif','WriteMode','append','DelayTime',0.2);
        end
    end
end
% C = rand_c;
end

测试代码如下,如果是单纯是为了处理图像,可以将“聚类”这小段的代码重新封装成一个function。

clear;
close all;
clc;
tic
%% 读取数据
img=imread('city.png');
% img = rgb2gray(img);
%% 聚类
m = size(img, 1);
n = size(img, 2);
p = size(img, 3);
k = 4;
[C, label, J2] = my_kmeans(img, k, 1, 1);
% 使用gather函数将gpuarray转换为普通数组
C = gather(C);
C = uint8(C);
% randn('seed', sum(100*clock))
% sprintf('seed=%d', sum(100*clock))
% rand_c = rand(k,3)*255;
% C = uint8(rand_c);
label = uint8(label);
temp = C(label,:);
dst = reshape(temp, m, n, []);%转换成图片矩阵的格式
toc
%% 显示结果
figure
subplot(221), imshow(img,[]);
subplot(222), imshow(dst,[]);
subplot(212), plot(J2), xlabel('iters'), ylabel('norm diff')

测试结果

测试的原始图片如下:
在这里插入图片描述
聚类过程如下,是不是有种延时摄影的感觉。
在这里插入图片描述
测试结果及相应的迭代过程如下所示:
在这里插入图片描述

MATLAB自带函数不同K值下的效果:
在这里插入图片描述
自己实现的不同K值下的效果:
在这里插入图片描述
MATLAB自带函数的效果和我实现的效果有所区别,主要是由于MATLAB自带函数采用了kmeans++进行了优化,在此就不赘述了,感兴趣的朋友可以去深入了解。

参考文献

[1] 机器学习实战——K-means聚类图像分割
[2] 基于K均值聚类算法的图像分割(Matlab)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1530582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java:类和对象

目录 1.面对对象的初步认识1.1 什么是面向对象&#xff1f;&#xff08;Java当中一切皆为对象&#xff09;1.2 面对对象与面对过程 2.类的定义和使用2.1简单认识类2.2 类的定义格式 3.类的实例化3.1 什么是实例化3.2类和对象的说明 4.this引用4.1为什么要使用this引用4.2 什么是…

集合系列(十) -Set接口详解

一、摘要 关于 Set 接口&#xff0c;在实际开发中&#xff0c;其实很少用到&#xff0c;但是如果你出去面试&#xff0c;它可能依然是一个绕不开的话题。 言归正传&#xff0c;废话咱们也不多说了&#xff0c;相信使用过 Set 集合类的朋友都知道&#xff0c;Set集合的特点主要有…

重磅:Python 迎来多线程重大更新 no-GIL

“在 Python 中&#xff0c;GIL 将不复存在。对 AI 生态系统来说是巨大的胜利。”PyTorch 核心维护者 Dmytro Dzhulgakov 感慨地说道。 GIL 是什么&#xff1f;GIL 的全称是 Global Interpreter Lock&#xff08;全局解释器锁&#xff09;&#xff0c;这不仅是 Python 的特性…

计算机毕业设计-基于python的旅游信息爬取以及数据分析

概要 随着计算机网络技术的发展&#xff0c;近年来&#xff0c;新的编程语言层出不穷&#xff0c;python语言就是近些年来最为火爆的一门语言&#xff0c;python语言&#xff0c;相对于其他高级语言而言&#xff0c;python有着更加便捷实用的模块以及库&#xff0c;具有语法简单…

彻底学会系列:一、机器学习之梯度下降(2)

1 梯度具体是怎么下降的&#xff1f; ∂ J ( θ ) ∂ θ \frac{\partial J (\theta )}{\partial \theta} ∂θ∂J(θ)​&#xff08;损失函数&#xff1a;用来衡量模型预测值与真实值之间差异的函数&#xff09; 对损失函数求导&#xff0c;与学习率相乘&#xff0c;按梯度反方…

mabatis 下

mybatis 原生的API&注解的方式MyBatis-原生的API调用快速入门需求快速入门代码实现 MyBatis-注解的方式操作快速入门需求快速入门代码实现注意事项和说明 mybatis-config.xml配置文件详解说明properties属性settings全局参数定义typeAliases别名处理器typeHandlers类型处理…

长安链团队论文入选国际顶会Usenix Security 2024

零知识证明是区块链扩容和隐私保护的关键前沿技术&#xff0c;其天然具备完备性、可靠性和零知识性的特点&#xff0c;是提升区块链交易吞吐量与可扩展性、在验证用户身份的同时保护用户数据隐私&#xff0c;实现复杂计算不可或缺的关键技术。基于零知识证明技术实现高兼容性、…

C++ 组合 委托 继承 组合使用

关于组合和委托看C中的组合&#xff0c;委托和继承 - 知乎 (zhihu.com) 继承和组合关系下的构造和析构 ​ 还有一种情况 ​ 构造函数由内到外&#xff0c;析构由外到内。 委托和继承关系组合 设计模式-观察者模式&#xff08;Observer&#xff09; ​ 如下图左边&#x…

稀碎从零算法笔记Day22-LeetCode:

题型&#xff1a;链表 链接&#xff1a;2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;Leet 题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 …

MySQL表的增删改查(基础版本)

MySQL的增删改查也就是CRUD CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete)四个单词的首字母缩写。 1.新增 1.1 语法&#xff1a; INSERT [INTO] table_name [(column [, column] ...)] VALUES (value_list) [, (value_list)] ... value_list: value, [,…

【C语言】遍历目录树

在 Linux 环境下&#xff0c;如果编写程序且需要通过函数接口来遍历目录树&#xff0c;可以考虑使用以下几个常用的调用&#xff1a; 1. opendir() / readdir() / closedir()&#xff1a; 这是 POSIX 标准定义的函数&#xff0c;用于遍历目录。opendir() 用于打开一个目录&…

【C语言】access和stat函数

access 在C语言中&#xff0c;access 函数是一个用于检查文件的存在性以及对文件的访问权限的函数。它定义在 <unistd.h> 头文件中&#xff0c;通常在 Unix 系统中可用。这个函数可以用来验证当前用户是否有权访问指定的文件&#xff0c;以及这些权限的类型。 access 函…

express+mysql+vue,从零搭建一个商城管理系统16--收货地址(全国省市县名称和code列表)

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、新建config/area.js二、新建models/address.js三、新建dao/address.js四、新建routes/address.js五、添加地址六、查询用户地址列表总结 前言 需求&#xff1a;主要学习express&#xff0c;所以先写serv…

微积分基础概念和在AI中的应用

基本概念 微积分是数学中的一个主要分支&#xff0c;专注于研究函数、极限、导数、积分等的理论。它是现代科学和工程中不可或缺的基础工具&#xff0c;尤其在处理变化率和累积量的问题时显得尤为重要。微积分通常分为两大部分&#xff1a;微分学和积分学。 微分学 微分学关…

NASA数据集——2017 年阿拉斯加和加拿大上空彩色红外图像中的 AirSWOT 水掩模数据集

简介 ABoVE: AirSWOT Water Masks from Color-Infrared Imagery over Alaska and Canada, 2017 摘要 本数据集提供了&#xff1a;1&#xff09;用于未来从共存的 AirSWOT Ka 波段干涉测量数据中提取水面高程 (WSE) 的保守开放水域掩膜&#xff1b;2&#xff09;沿 NASA 北极-…

宋仕强论道之华强北科技创新说

宋仕强论道之华强北科技创新说&#xff0c;“创新”是深圳市和华强北灵魂&#xff0c;创新再加上敢想敢干永不言败&#xff0c;造就了深圳市经济奇迹和华强北财富神话&#xff01;首次在深圳市落槌的“土地拍卖”&#xff0c;华强北“一米柜台”赋予独立经营权&#xff0c;把最…

Springboot通过注解+切面实现接口权限校验

Springboot通过注解&#xff0b;切面实现接口权限校验 主要说一下在对接口请求时&#xff0c;如何用注解切面去拦截校验当前登录用户是否有访问权限 1.首先创建注解 HasPermission &#xff0c;跟普通注解创建方式基本一致 Retention(RetentionPolicy.RUNTIME) Target(Element…

Python矩阵计算

文章目录 求积求逆最小二乘法特征值 Python科学计算&#xff1a;数组&#x1f4af;数据生成&#x1f4af;数据交互&#x1f4af;微积分&#x1f4af;插值&#x1f4af;拟合&#x1f4af;FFT&#x1f4af;卷积&#x1f4af;滤波&#x1f4af;统计 求积 矩阵是线性代数的核心对…

JVM 垃圾回收机制:探秘对象生死判定与高效回收算法

目录 一、JVM 对象生死判定 1.1 引用技术算法 1.2 可达性分型算法 二、引用 三、 回收方法区 四、垃圾回收算法 4.1 标记-清楚算法 4.2 标记-复制算法 4.3 标记-整理算法 JVM 程序计数器、虚拟机栈、本地方法栈随着线程而生&#xff0c;随着线程而灭。栈中的栈帧随着方法的…

相约CHWE全球跨境电商展,3月20日凯琦等你来!

凯琦又要和大家线下见面啦&#xff01; 2024年3月20日-22日&#xff0c;第三届CHWE全球跨境电商展将于深圳福田会展中心盛大开幕。该展会汇聚海内外平台、服务生态及海外线下渠道&#xff0c;助力企业快速扩大市场覆盖面和销售渠道&#xff0c;驱动品牌增长。 本次大会&#…