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

文章目录

    • 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 >= 3is_gpu = 1;
elseis_gpu = 0;
end
if nargin == 4is_show = 1;
elseis_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_gpuX = 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 trueiter = 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:kC(i, :) = mean(X(label == i , :)); %取新的k个聚类中心endJ_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;endif (iter==100)  %设置强制截断的迭代次数break;endJ_prev = J_cur;if is_show% 录制gifrand_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 == 1imwrite(data,map,'test.gif','gif','Loopcount',inf,'DelayTime',0.2);elseimwrite(data,map,'test.gif','gif','WriteMode','append','DelayTime',0.2);endend
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.hqwc.cn/news/540643.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PBKDF2算法:保障密码安全的利器

title: PBKDF2算法&#xff1a;保障密码安全的利器 date: 2024/3/14 16:40:05 updated: 2024/3/14 16:40:05 tags: PBKDF2算法密码安全性迭代盐值密钥 PBKDF2算法起源&#xff1a; PBKDF2&#xff08;Password-Based Key Derivation Function 2&#xff09;算法是一种基于密码…

Android和IOS应用开发-Flutter 应用中实现记录和使用全局状态的几种方法

文章目录 在Flutter中记录和使用全局状态使用 Provider步骤1步骤2步骤3 使用 BLoC步骤1步骤2步骤3 使用 GetX&#xff1a;步骤1步骤2步骤3 在Flutter中记录和使用全局状态 在 Flutter 应用中&#xff0c;您可以使用以下几种方法来实现记录和使用全局状态&#xff0c;并在整个应…

Tomcat会话保持

文章目录 Tomcat会话保持1、代理服务器配置2、web服务器配置3、会话保持3.1 方法一&#xff1a;修改代理服务器配置&#xff08;nginx&#xff09;3.2 方法二&#xff1a;修改web服务器配置&#xff08;tomcat&#xff09;访问官方文档&#xff0c;查看需要添加的配置文件修改t…

声通科技:CoAI交互式人工智能领域的创新领军者

在人工智能的浪潮中&#xff0c;交互式人工智能&#xff08;CoAI&#xff09;以其独特的优势&#xff0c;正逐渐改变着人们的生活方式和工作模式。作为中国企业级信息技术解决方案提供商&#xff0c;上海声通信息科技股份有限公司&#xff08;下文称&#xff1a;声通科技&#…

所有现在的天坑专业都有着无比辉煌的过往

同理&#xff0c;现在辉煌的专业&#xff0c;将来也必然走下神坛。 工匠的发展与兴衰趋势-机器人篇 1024-2023-珍爱生命远离成功学 大学专业发展史&#xff1a;从辉煌银河到天坑深渊 大学专业的发展史&#xff0c;宛如一部波澜壮阔的史诗&#xff0c;既有“飞流直下三千尺”…

运行gazebo机器人模型没有cmd_vel话题

运行赵虚左教程代码出现上诉问题 roslaunch urdf02_gazebo demo03_env.launch 原因&#xff1a;缺少某个包 在工作空间catkin_make编译发现报错 解决&#xff1a; sudo apt-get install ros-noetic-gazebo-ros-pkgs ros-noetic-gazebo-ros-control 下载后再次运行launch文件…

亚马逊一款床架热评超10w+!赛盈分销选品指南助力卖家撬动海外新机会

人的一天至少有8个小时是在床上的&#xff0c;床上用品成为人们日常生活的刚需。 但有研究表明&#xff0c;在生活各方面的施压下&#xff0c;每年就有7千万的美国人产生睡眠障碍。为了提升睡眠质量&#xff0c;相关功能性和刚需类的商品需求暴增&#xff0c;加速推动了睡眠经济…

Linux下的多线程编程:原理、工具及应用(1)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Flower of Life—陽花 0:34━━━━━━️&#x1f49f;──────── 4:46 &#x1f504; ◀️ ⏸ ▶️ ☰ …

搜索:DFS与BFS

DFS与BFS为图论中的概念。在搜索算法中&#xff0c;该词常常指利用递归函数方便地实现暴力枚举的算法&#xff0c;与图论中的 DFS 算法有一定相似之处&#xff0c;但并不完全相同。BFS 在搜索中&#xff0c;将每个状态对应为图中的一个点即可。 DFS&#xff08;搜索&#xff0…

使用IDF和VSCode构建ESP32的开发环境

目录 概述 1 安装ESP32开发环境IDF 1.1 下载软件 1.2 安装软件 1.3 配置环境参数 1.4 VSCode中配置IDF插件 1.5 配置烧写代码方式 2 在使用vscode创建工程 2.1 创建工程模版 2.2 工程目录介绍 3 编译和下载 3.1 认识 VSCode下idf编译环境 3.2 编译代码 3.2.1 认识…

数据结构:静态链表(编程技巧)

链表的元素用数组存储&#xff0c; 用数组的下标模拟指针。 一、理解 如果有些程序设计语言没有指针类型&#xff0c;如何实现链表&#xff1f; 在使用指针类型实现链表时&#xff0c;我们很容易就可以直接在内存中新建一块地址用于创建下一个结点&#xff0c;在逻辑上&#x…

软件无线电系列——模拟无线电、数字无线电、软件无线电

本节目录 一、模拟无线电 二、数字无线电 1、窄带数字无线电 2、宽带数字无线电 三、软件无线电本节内容 一、模拟无线电 20世纪80年代的模拟体制(美国的AMPS/欧洲的TACS)被称为第一代移动通信&#xff0c;简称1G,主要目标是为在大范围内有限的用户提供移动电话服务。最主要的…