当前位置: 首页 > news >正文

【基于Kmeans、Kmeans++和二分K均值算法的图像分割】数据挖掘实验三

文章目录

  • Ⅰ、项目任务要求
  • II、原理描述
    • KMeans
    • KMeans++
    • 二分K均值
    • 评价指标-轮廓系数
  • III、数据集描述
  • IV、具体实现过程
  • V、结果分析
  • VI、完整代码
  • VII、深度学习与图片分割(补充)
    • CNN
      • 1. 卷积层(Convolutional Layer):
      • 2. 激活函数(Activation Function):
      • 3. 池化层(Pooling Layer):
      • 4. 全连接层(Fully Connected Layer):
      • 工作原理:
    • 分割效果


Ⅰ、项目任务要求

  • 图像分割 是图像处理和计算机视觉中重要的一环,在实际生活中得到了广泛的应用。例如:
    • 在医学上,用于测量医学图像中组织体积、三维重建、手术模拟等;
    • 在遥感图像中,分割合成孔径雷达图像中的目标、提取遥感云图中不同云系与背景等、定位卫星图像中的道路和森林等。
  • 图像分割也可作为预处理将最初的图像转化为若干个更加抽象、更便于计算机处理的形式,既保留了图像中的重要特征信息,又有效减少了图像中的无用数据、提高了后续图像处理的准确率和效率。例如:
    • 在通信方面,可事先提取目标的轮廓结构、区域内容等,保证不失有用信息的同时,有针对性地压缩图像,以提高网络传输效率;
    • 在交通领域可用来对车辆进行轮廓提取、识别或跟踪,行人检测等。
  • 总的来说,凡是与目标的检测、提取和识别等相关的内容,都需要利用到图像分割技术。因此,无论是从图像分割的技术和算法,还是从对图像处理、计算机视觉的影响以及实际应用等各个方面来深入研究和探讨图像分割,都具有十分重要的意义。
  • 聚类技术 是图像分割技术中重要组成部分,其中特征空间聚类法,如Kmeans算法及其相应变体是划分聚类方法中的典范。利用特征空间聚类法进行图像分割是将图像空间中的像素用对应的特征空间点表示,根据它们在特征空间的聚集对特征空间进行分割,然后将它们映射回原图像空间,得到分割结果。

任务描述

  • 本次实验利用图像的灰度、颜色、纹理、形状等特征,把图像分成若干个互不重叠的区域,并使这些特征在同一区域内呈现相似性,在不同的区域之间存在明显的差异性。然后就可以将分割的图像中具有独特性质的区域提取出来用于不同的研究
  • 实验内容:分别用KmeansKmeans++二分K均值三种聚类方法对图片进行图像分割,并写出实验结果分析。

主要任务要求

  • 简述三种算法思想和实现原理。
  • 小组每人准备一张自己喜欢的图片(图片种类多样化)
  • 写出实验结果分析:
    • 实验运行环境描述。如开发平台、编程语言、调参情况等。
    • 不同初始簇数下三种方法对图片的分割效果对比、分析。
      • 对比表样式如下所示,可将分割效果图分别粘贴到对应位置;
      • 采用轮廓系数(或其它评价指标)评估三种方法的聚类效果(见参考资料网址);
      • 结合对比表(表样如下)结果和评估结果对实验结果进行分析说明。
        在这里插入图片描述

II、原理描述

KMeans

KMeans++

二分K均值

评价指标-轮廓系数


III、数据集描述


IV、具体实现过程


V、结果分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


VI、完整代码

import numpy as np
import PIL.Image as Image
from sklearn.cluster import KMeans, Birch
from sklearn.metrics import silhouette_score, pairwise_distances
import matplotlib.pyplot as plt# 设置Matplotlib的文本渲染器和支持中文字符的字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 或者 ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False  # 用于显示负号(-)的正常显示# Todo: 准备数据集 ------------------------------------------------------------
# todo: 定义函数loadData来处理图片
# 常量
NORMALIZATION_FACTOR = 256# todo: 加载数据的函数
def load_data(file_path):with open(file_path, 'rb') as f:img = Image.open(f)m, n = img.sizedata = []for i in range(m):for j in range(n):x, y, z = img.getpixel((i, j))data.append([x / NORMALIZATION_FACTOR, y / NORMALIZATION_FACTOR, z / NORMALIZATION_FACTOR])return np.asarray(data), m, n# Todo: 计算轮廓系数的函数 ------------------------------------------------------------
def silhouette_coefficient(X, labels):cluster_centers = [np.mean(X[labels == i], axis=0) for i in range(len(set(labels)))]distances = pairwise_distances(X, cluster_centers)a = np.array([np.mean(distances[labels == i, i]) for i in range(len(set(labels)))])b = np.array([np.min(distances[labels != i, i]) for i in range(len(set(labels)))])s = (b - a) / np.maximum(a, b)return np.mean(s)# Todo: 使用KMeans、KMeans++和二分K均值进行图像分割 ------------------------------------------------------------
# 加载图片并处理
image_paths = ["data/demo3/input/img1.jpg","data/demo3/input/img2.jpg","data/demo3/input/img3.jpg","data/demo3/input/img4.jpg"]k_values = [2, 3, 4]# 初始化轮廓系数列表
kmeans_silhouette_scores = []
kmeans_plus_silhouette_scores = []
birch_silhouette_scores = []print("使用KMeans、KMeans++和二分K均值进行图像分割")
# 分割图片并计算轮廓系保存分割图片
for k in k_values:kmeans_scores = []kmeans_plus_scores = []birch_scores = []for idx, path in enumerate(image_paths):img_data, rows, cols = load_data(path)# 计算KMeans聚类的轮廓系数kmeans_labels = KMeans(n_clusters=k, init='random', n_init=10).fit_predict(img_data)kmeans_silhouette_avg = silhouette_coefficient(img_data, kmeans_labels.flatten())kmeans_scores.append(kmeans_silhouette_avg)# 计算KMeans++聚类的轮廓系数kmeans_plus_labels = KMeans(n_clusters=k, init='k-means++', n_init=10).fit_predict(img_data)kmeans_plus_silhouette_avg = silhouette_coefficient(img_data, kmeans_plus_labels.flatten())kmeans_plus_scores.append(kmeans_plus_silhouette_avg)# 计算二分K均值聚类的轮廓系数birch_labels = Birch(n_clusters=k, threshold=0.01, branching_factor=50).fit_predict(img_data)birch_silhouette_avg = silhouette_coefficient(img_data, birch_labels.flatten())birch_scores.append(birch_silhouette_avg)print(f"使用{k}个聚类中心的K均值聚类对图片{idx + 1}的轮廓系数为: {kmeans_silhouette_avg}")print(f"使用{k}个聚类中心的K++均值聚类对图片{idx + 1}的轮廓系数为: {kmeans_plus_silhouette_avg}")print(f"使用{k}个聚类中心的二分K均值聚类对图片{idx + 1}的轮廓系数为: {birch_silhouette_avg}")# 保存分割的图片kmeans_output_path = f"data/demo3/output/KMeans{k}-{idx + 1}.jpg"kmeans_plus_output_path = f"data/demo3/output/KMeans++{k}-{idx + 1}.jpg"birch_output_path = f"data/demo3/output/Birch{k}-{idx + 1}.jpg"segmented_img_kmeans = np.reshape(kmeans_labels, (rows, cols))segmented_img_kmeans = (segmented_img_kmeans * 255 / k).astype(np.uint8)segmented_img_kmeans = Image.fromarray(segmented_img_kmeans)segmented_img_kmeans.save(kmeans_output_path)segmented_img_kmeans_plus = np.reshape(kmeans_plus_labels, (rows, cols))segmented_img_kmeans_plus = (segmented_img_kmeans_plus * 255 / k).astype(np.uint8)segmented_img_kmeans_plus = Image.fromarray(segmented_img_kmeans_plus)segmented_img_kmeans_plus.save(kmeans_plus_output_path)segmented_img_birch = np.reshape(birch_labels, (rows, cols))segmented_img_birch = (segmented_img_birch * 255 / k).astype(np.uint8)segmented_img_birch = Image.fromarray(segmented_img_birch)segmented_img_birch.save(birch_output_path)# 计算平均轮廓系数mean_kmeans_score = np.mean(kmeans_scores)mean_kmeans_plus_score = np.mean(kmeans_plus_scores)mean_birch_score = np.mean(birch_scores)# 存储平均轮廓系数kmeans_silhouette_scores.append(mean_kmeans_score)kmeans_plus_silhouette_scores.append(mean_kmeans_plus_score)birch_silhouette_scores.append(mean_birch_score)# Todo: 可视化KMeans、KMeans++和二分K均值聚类的轮廓系数 ------------------------------------------------------------
print("【平均轮廓系数】")
print(f"K均值:{kmeans_silhouette_scores}")
print(f"K++均值:{kmeans_plus_silhouette_scores}")
print(f"二分K均值:{birch_silhouette_scores}")plt.figure(figsize=(10, 6))
plt.plot(k_values, kmeans_silhouette_scores, marker='o', label='KMeans')
plt.plot(k_values, kmeans_plus_silhouette_scores, marker='o', label='KMeans++')
plt.plot(k_values, birch_silhouette_scores, marker='o', label='Birch')
plt.xlabel('聚类中心数量')
plt.ylabel('轮廓系数')
plt.title('KMeans、KMeans++和Birch聚类的平均轮廓系数')
plt.xticks(k_values)
plt.legend()
plt.grid(True)
plt.show()# Todo: 可视化聚类结果 ------------------------------------------------------------
plt.figure(figsize=(12, 8))
for i, k in enumerate(k_values):plt.subplot(1, len(k_values), i + 1)for idx, path in enumerate(image_paths):segmented_img = Image.open(f"data/demo3/output/KMeans{k}-{idx + 1}.jpg")plt.imshow(segmented_img, cmap='gray')plt.axis('off')plt.title(f'KMeans 聚类结果\n(聚类数:{k})')plt.show()plt.figure(figsize=(12, 8))
for i, k in enumerate(k_values):plt.subplot(1, len(k_values), i + 1)for idx, path in enumerate(image_paths):segmented_img = Image.open(f"data/demo3/output/KMeans++{k}-{idx + 1}.jpg")plt.imshow(segmented_img, cmap='gray')plt.axis('off')plt.title(f'KMeans++ 聚类结果\n(聚类数:{k})')plt.show()plt.figure(figsize=(12, 8))
for i, k in enumerate(k_values):plt.subplot(1, len(k_values), i + 1)for idx, path in enumerate(image_paths):segmented_img = Image.open(f"data/demo3/output/Birch{k}-{idx + 1}.jpg")plt.imshow(segmented_img, cmap='gray')plt.axis('off')plt.title(f'Birch 聚类结果\n(聚类数:{k})')plt.show()

VII、深度学习与图片分割(补充)

CNN

卷积神经网络(CNN)是一种专门用于处理网格状数据(比如图像和视频)的深度学习模型。CNN在图像识别、物体检测、图像生成等任务上取得了很大的成功,它的核心特点是可以自动从数据中学习到特征,而不需要手动设计特征提取器。

以下是CNN的主要组成部分和工作原理:

1. 卷积层(Convolutional Layer):

卷积层是CNN的核心。它使用卷积操作来提取图像中的特征。卷积操作通过一个小的窗口(卷积核)在输入图像上滑动,计算每个窗口内的值,然后生成输出特征图。这种操作可以捕捉到图像中的局部特征,因此非常适合处理图像数据。

2. 激活函数(Activation Function):

激活函数引入了非线性性质,使得网络可以学习复杂的模式。常用的激活函数包括ReLU(Rectified Linear Unit)函数,Sigmoid函数和TanH函数。

3. 池化层(Pooling Layer):

池化层用于减小特征图的空间尺寸,同时保留重要的特征。最常见的池化操作是最大池化(Max Pooling),它选择每个区域内的最大值作为输出,从而减小特征图的大小。

4. 全连接层(Fully Connected Layer):

全连接层将前面卷积层和池化层提取到的特征映射转化为网络最终的输出。全连接层的每个神经元与前一层的所有神经元相连接,通过学习权重来进行特征的组合和分类。

工作原理:

  1. 输入数据:CNN的输入通常是一个三维数组,表示图像的高度、宽度和通道数(比如RGB图像有三个通道,灰度图像只有一个通道)。

  2. 卷积和激活:输入数据经过卷积层和激活函数,得到一系列特征图,每个特征图代表不同的特征。

  3. 池化:特征图通过池化层进行下采样,减小空间尺寸,同时保留重要特征。

  4. 全连接:池化层的输出被展开成一个一维向量,输入到一个或多个全连接层中,进行分类或回归等任务。

CNN的主要优势在于它可以自动学习到输入数据中的空间结构特征,而不需要手动设计特征提取器。这使得它在图像识别等任务上表现得非常出色。

分割效果

相关文章:

【基于Kmeans、Kmeans++和二分K均值算法的图像分割】数据挖掘实验三

文章目录 Ⅰ、项目任务要求II、原理描述KMeansKMeans二分K均值评价指标-轮廓系数 III、数据集描述IV、具体实现过程V、结果分析VI、完整代码VII、深度学习与图片分割(补充)CNN1. 卷积层(Convolutional Layer):2. 激活函…...

深入理解Java CompletableFuture并发编程模型

摘要:本文将介绍Java中的CompletableFuture类,探讨其在并发编程中的应用。我们将详细讨论CompletableFuture的特性、常见用法和最佳实践,帮助开发人员更好地利用这个强大的工具进行异步编程。 1. 什么是CompletableFuture? Compl…...

TensorFlow手动加载数据集(以mnist为例)

在进行Mnist手写识别的项目中,出现了Mnist数据集下载出错的问题,报出以下错误: Exception: URL fetch failure on https://s3.amazonaws.com/img-datasets/mnist.npz: None – [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主…...

C++项目实战——基于多设计模式下的同步异步日志系统(总集篇)

文章目录 专栏导读项目介绍开发环境核心技术环境搭建日志系统介绍1.为什么需要日志系统2.日志系统技术实现2.1同步写日志2.2异步写日志 前置知识补充不定参函数C风格不定参函数不定参宏函数设计模式六大原则单例模式饿汉模式懒汉模式 工厂模式简单工厂模式工厂方法模式抽象工厂…...

杨辉三角按列求和

假设求杨辉三角这一列 我们考虑这个格子: 然后对其不断展开 综上: ∑ i 0 n ( i k ) ( n 1 k 1 ) \sum_{i0}^n\binom i k\binom {n1}{k1} i0∑n​(ki​)(k1n1​) ∑ i l r ( i k ) ( r 1 k 1 ) − ( l k 1 ) \sum_{il}^r\binom i k\binom{r1}{k…...

C复习-语句

参考: 里科《C和指针》 语句 C没有bool,是用整型代替的。因此if(expression)中,expression只要是可以产生整型结果即可,且0表示假,非0表示真。 如果有只靠缩进没有{}的else语句,会自动匹配离它最近的、不…...

[Python进阶] 操纵键盘:PyAutoGUI

6.5 操纵键盘:PyAutoGUI 6.5.1 keyDown、keyUp 按下或弹起某个按键。在按下时不会释放。 参数: key(str): 要按下的键。有效的名称列在KEYBOARD_KEYS。 logScreenshot:是否要截图并保存在当前文件夹下。 import pyautoguipyautogui.keyDown(f) # 模拟…...

jdbc快速开始

文章目录 快速开始参考文献 jdbc 就是使用java语言操作关系型数据库的一套api jdbc本质: 官方(sun公司)定义的一套操作所有关系型数据库的规则,就是接口各个数据库厂商去实现这套接口,提供数据库驱动jar包我们可以使用这套接口编程&#xff…...

C语言中static关键字用法

C语言中static关键字用法 2021年7月28日席锦 static关键字在c语言中比较常用,使用恰当能够大大提高程序的模块化特性,有利于扩展和维护。但是对于c语言初学者,static由于使用灵活,并不容易掌握。 变量 1.局部变量 普通局部变量是再…...

STM32-LCD液晶显示

LCD液晶显示 针对野火指南者配套资料:3.2寸 LCD电阻屏,屏幕里自带ILI9341液晶控制器芯片,该控制器芯片中存在GRAM(即显存)。该液晶控制器使用8080接口与单片机通讯,液晶面板引出来的FPC信号线为8080接口&am…...

GraphQL 查询:一个全面指南

GraphQL GraphQL 是一种 API 查询语言和运行时,用于使用现有数据完成这些查询。它为您的 API 中的数据提供了完整且易于理解的描述,让客户能够准确地询问他们需要什么,更容易随着时间的推移发展 API,并启用强大的开发人员工具。 …...

快速自动化处理JavaScript渲染页面的方法

目录 一、使用无头浏览器 二、使用JavaScript渲染引擎 三、使用前端框架工具 随着互联网技术的不断发展,JavaScript已经成为Web开发中不可或缺的一部分。然而,在自动化处理JavaScript渲染页面方面,却常常让开发者感到头疼。本文将介绍一些快…...

[计算机提升] 系统及用户操作

1.4 系统及用户操作 1.4.1 系统操作 1.4.1.1 开机、关机、重启 在Windows系统中,开机(Power On),关机(Shutdown)和重启(Restart)是指计算机的不同电源控制操作。 开机:…...

Linux篇 四、Linux修改用户名

Linux系列文章目录 一、香橙派Zero2设置开机连接wifi 二、香橙派Zero2获取Linux SDK源码 三、香橙派Zero2搭建Qt环境 文章目录 Linux系列文章目录前言一、更改用户名准备二、修改用户名总结 前言 想要把Ubuntu的普通用户名修改成自己想要的 一、更改用户名准备 LubanCat 镜像…...

【Element-plus】如何让滚动条永远在最底部(支持在线演示)

如何让滚动条永远在最底部 一、适用场景二、实现思路三、效果图四、在线演示五、完整代码 一、适用场景 在某些场景下,你可能希望滚动条保持在最底部,以确保用户始终看到最新的内容或信息。如:在实时聊天应用程序中,当新消息到达…...

解决方案-LBS用户位置Redis-GEO附近人/店铺

附近人 windows安装附近人列表功能mysqlredis GEO CNNVD-201511-230 未授权访问python 多线程 redis大端模式与小端模式IP地址的不同表现形式1.字符串表现形式2. 整数表现形式3.大小端模式下的IP地址 0x01 进入python正题Python的socket库1.socket.socket(family,type)2.socket…...

springboot+html实现简单注册登录

前端&#xff1a; register.html <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>register</title><link rel"stylesheet" type"text/css" href"/css/style.css&…...

ESP32网络开发实例-Web控制8路继电器

Web控制8路继电器 文章目录 Web控制8路继电器1、继器器介绍2、软件准备3、硬件准备4、代码实现4.1 单路继电器控制灯泡4.2 Web控制8路继电器将继电器与 ESP32 一起使用是远程控制交流家用电器的好方法。 本文介绍如何使用 ESP32 控制继电器模块。 我们将了解继电器模块的工作原…...

Flutter ☞ 变量

在Flutter中&#xff0c;变量分为两种类型 弱类型强类型 弱类型 var 如果没有初始值&#xff0c;可以变成任何类型 var a; // var a ; // 一旦赋值&#xff0c;就确定类型&#xff0c;不能随意改动 a abc; a 123; a true; a {key: 123}; a [abc];print(a)Object 动…...

冲刺十五届蓝桥杯P0006平面切分

文章目录 题目思路代码总结 题目 平面切分 思路 这道题是一个思维题把&#xff0c;之前没有接触过平面几何的知识&#xff0c;做起来感觉还是比较难的&#xff0c;用到的set集合和自己创建一个类 首先我们知道&#xff0c;一根直线A是可以将平面切分成两块的&#xff0c;如…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...