opencv实战项目十六:kmeans图像颜色聚类:


前言

在数字化时代,图像处理技术已成为计算机视觉领域的重要组成部分。其中,图像颜色聚类作为一项关键技术在众多应用场景中发挥着重要作用,如图像分割、物体识别、色彩调整等。K-means算法作为一种经典的聚类方法,以其简洁、高效的特点在图像颜色聚类领域得到了广泛应用。本文将围绕K-means图像颜色聚类技术,探讨其原理、实现方法以及在实际应用中的价值,为广大图像处理爱好者和技术人员提供参考。

K-means介绍

K-means算法是一种基于距离的聚类方法,它旨在将一组数据点划分为K个簇(Cluster),其中每个簇的内部数据点尽可能相似,而不同簇的数据点尽可能不同。
K-means算法的核心思想是通过迭代过程将数据点分配到K个簇中,使得每个数据点与其所属簇的中心点(均值)的距离之和最小。算法的步骤如下:

初始化: 随机选择K个数据点作为初始簇中心。
分配: 对于每个数据点,计算其与各个簇中心的距离,并将其分配到最近的簇中心所代表的簇。
更新: 重新计算每个簇的数据点的平均值,作为新的簇中心。
迭代: 重复步骤2和步骤3,直到满足停止条件,如簇中心的变化小于某个阈值或达到预设的迭代次数。

在opencv中集成了k-means方法,其函数为cv2.kmeans()函数介绍:
cv2.kmeans()函数是实现K-means聚类算法的一个高效工具。这个函数可以用于对数据进行聚类分析,特别是在图像处理中,它常用于颜色量化,即将图像中的颜色缩减到一定数量的聚类中心所代表的颜色。

retval, bestLabels, centers = cv2.kmeans(data, K, bestLabels, criteria, attempts, flags)
参数说明:
data: 一个浮点型数组,每一行代表一个样本,每一列代表一个特征。在图像颜色聚类中,通常是一个(N, 3)的数组,N是像素点的数量,3代表颜色通道(例如RGB)。
K: 聚类的数目,即我们想要将数据点划分成的簇的数量。
bestLabels: 输出数组,用于存储每个样本的簇索引。如果提供,则该数组将被用作初始标签,并且函数将使用这些标签进行优化。
criteria: 聚类算法的终止条件,这是一个包含三个元素的元组:type,max_iter,epsilon。
type:用于指定停止标准的类型,通常使用cv2.TERM_CRITERIA_EPS或cv2.TERM_CRITERIA_MAX_ITER,或者两者的组合。
max_iter:最大的迭代次数。
epsilon:所需的准确度。

attempts: 使用不同初始标签执行算法的次数,算法会返回最佳聚类的结果。
flags: 用于指定初始中心的选取方法,可以是cv2.KMEANS_PP_CENTERS或cv2.KMEANS_RANDOM_CENTERS。默认值为cv2.KMEANS_PP_CENTERS,它使用K-means++算法来选择初始中心,这通常比随机选择更有效。

返回值:

retval: 聚类中心之间的最小平方距离。
bestLabels: 每个样本的簇索引数组。
centers: 聚类中心的数组,每一行代表一个簇中心。

使用案例:

# 导入所需的库
import numpy as np
import cv2

# 读取输入图像
img = cv2.imread(r'D:\ultralytics-main\1724896328042.png')
z = img.reshape((-1,3))

# 转换为 np.float32
z = np.float32(z)

# 定义标准,聚类的数量K并应用kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 2
ret,label,center=cv2.kmeans(z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)

# 转换回uint8,并制作原始图像
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))

# 显示图像
cv2.imshow('k = 2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

注:K=2可以实现图像二值化的效果,与传统二值化相比K-means算法在图像二值化中展现出其独特的优势,它能够根据图像内容的特征自适应地选择阈值,从而在处理不同光照条件和复杂背景的图像时,找到更合适的阈值,这一点相较于传统的全局阈值二值化方法更具灵活性。并且,K-means不仅考虑了像素间的相对关系,而且其不依赖于图像的特定统计特性,使得该方法适用于包括灰度图像和彩色图像在内的各种类型。然而,K-means图像二值化也存在局限性,如对初始聚类中心选择的敏感性,以及可能不适用于所有图像类型,特别是在处理非常嘈杂的图像时,可能需要额外的预处理来提升二值化的效果。

效果

原图:
在这里插入图片描述
二值化图:
在这里插入图片描述
可以看到没有收到阴影的影响,分割出比较干净的二值图片

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV中的Kmeans算法可以用于颜色聚类,它通过将像素点聚类成不同的颜色组合,从而实现对图像颜色分割和分类。下面是一个简单的实例来说明如何使用OpenCV中的Kmeans算法进行颜色聚类。 首先,我们需要导入必要的库,并读取一张图像作为输入。假设我们要对这张图像进行颜色聚类聚类数为K。 ```python import cv2 import numpy as np # 读取图像 img = cv2.imread('image.jpg') ``` 接下来,我们需要将图像转换为一维矩阵,并将其转化为浮点型数据。 ```python # 将图像转换为一维矩阵 pixels = img.reshape(-1, 3) # 将数据转换为浮点型 pixels = np.float32(pixels) ``` 然后,我们可以使用OpenCV中的kmeans函数进行颜色聚类。该函数接受三个参数:数据集,聚类数K和停止条件。 ```python # 设置停止条件 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) # 运行Kmeans算法进行聚类 _, labels, centers = cv2.kmeans(pixels, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS) ``` Kmeans运行结束后,我们可以得到每个像素点所属的类别标签以及聚类中心的颜色值。然后,我们可以根据类别标签为每个像素点上色,以此进行颜色分割和分类。 ```python # 将类别标签转换为整数型 labels = np.uint8(labels) # 重新构建图像 segmented_img = centers[labels.flatten()].reshape(img.shape) # 显示图像 cv2.imshow("Original Image", img) cv2.imshow("Segmented Image", segmented_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 最后,我们可以通过展示原始图像聚类后的图像来观察聚类的效果。 这就是使用OpenCVKmeans算法进行颜色聚类的简单实现。您可以根据实际需求调整聚类数和停止条件来得到更好的聚类效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值