python中opencv K均值聚类的实现示例

目录
  • K均值聚类
    • K均值聚类的基本步骤
    • K均值聚类模块
    • 简单例子

K均值聚类

  • 预测的是一个离散值时,做的工作就是“分类”。
  • 预测的是一个连续值时,做的工作就是“回归”。

机器学习模型还可以将训练集中的数据划分为若干个组,每个组被称为一个“簇(cluster)”。这种学习方式被称为“聚类(clusting)”,它的重要特点是在学习过程中不需要用标签对训练样本进行标注。也就是说,学习过程能够根据现有训练集自动完成分类(聚类)。

根据训练数据是否有标签,可以将学习划分为监督学习和无监督学习。

K近邻、支持向量机都是监督学习,提供有标签的数据给算法学习,然后对数据分类

聚类是无监督学习,事先并不知道分类标签是什么,直接对数据分类。

聚类能够将具有相似属性的对象划分到同一个集合(簇)中。

聚类方法能够应用于所有对象,簇内的对象越相似,聚类算法的效果越好。

K均值聚类的基本步骤

K均值聚类是一种将输入数据划分为k个簇的简单的聚类算法,该算法不断提取当前分类的中心点(也称为质心或重心),并最终在分类稳定时完成聚类。

从本质上说,K均值聚类是一种迭代算法。

在实际处理过程中需要进行多轮的迭代,直到分组稳定不再发生变化,即可认为分组完成。

K均值聚类算法的基本步骤如下:

  • 随机选取k个点作为分类的中心点。
  • 将每个数据点放到距离它最近的中心点所在的类中。
  • 重新计算各个分类的数据点的平均值,将该平均值作为新的分类中心点。
  • 重复步骤2和步骤3,直到分类稳定。

可以是随机选取k个点作为分类的中心点,也可以是随机生成k个并不存在于原始数据中的数据点作为分类中心点。

距离最近: 要进行某种形式的距离计算。(在具体实现时,可以根据需要采用不同形式的距离度量方法。)

K均值聚类模块

OpenCV提供了函数cv2.kmeans()来实现K均值聚类。

该函数的语法格式为:

retval, bestLabels, centers=cv2.kmeans(data, K, bestLabels, criteria, attempts, flags)
  • data:输入的待处理数据集合,应该是np.float32类型,每个特征放在单独的一列中。
  • K:要分出的簇的个数,即分类的数目,最常见的是K=2,表示二分类。
  • bestLabels:表示计算之后各个数据点的最终分类标签(索引)。实际调用时,参数bestLabels的值设置为None。
  • criteria:算法迭代的终止条件。当达到最大循环数目或者指定的精度阈值时,算法停止继续分类迭代计算。该参数由3个子参数构成,分别为type、max_iter和eps。
    • type表示终止的类型,可以是三种情况

      • cv2.TERM_CRITERIA_EPS:精度满足eps时,停止迭代。
      • cv2.TERM_CRITERIA_MAX_ITER:迭代次数超过阈值max_iter时,停止迭代。
      • cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER:上述两个条件中的任意一个满足时,停止迭代。
  • max_iter:最大迭代次数。
  • eps:精确度的阈值。
  • attempts:在具体实现时,为了获得最佳分类效果,可能需要使用不同的初始分类值进行多次尝试。指定attempts的值,可以让算法使用不同的初始值进行多次(attempts次)尝试。
  • flags:表示选择初始中心点的方法,主要有以下3种。
    • cv2.KMEANS_RANDOM_CENTERS:随机选取中心点。
    • cv2.KMEANS_PP_CENTERS:基于中心化算法选取中心点。
    • cv2.KMEANS_USE_INITIAL_LABELS:使用用户输入的数据作为第一次分类中心点;如果算法需要尝试多次(attempts 值大于1时),后续尝试都是使用随机值或者半随机值作为第一次分类中心点。
  • retval:距离值(也称密度值或紧密度),返回 每个点到相应中心点距离的平方和(是一个数)。
  • bestLabels:各个数据点的最终分类标签(索引)。
  • centers:每个分类的中心点数据。

简单例子

例1:

随机生成一组数据,使用函数cv2.kmeans()对其分类。

  • 一组数据在[0,50]区间
  • 另一组数据在[200,250]区间
  • 使用函数cv2.kmeans()对它们分类。

主要步骤如下:

数据预处理

使用随机函数随机生成两组数据,并将它们转换为函数cv2.kmeans()可以处理的格式。

设置参数

设置函数cv2.kmeans()的参数形式。将参数criteria的值设置为“(cv2.TERM_CRITERIA_EPS+ cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)”,在达到一定次数或者满足一定精度时终止迭代。

调用函数cv2.kmeans()

调用函数cv2.kmeans(),获取返回值,用于后续步骤的操作。

确定分类

根据函数cv2.kmeans()返回的标签(“0”和“1”),将原始数据分为两组

显示结果

绘制经过分类的数据及中心点,观察分类结果。

完整程序:

import numpy as np 
import cv2 
from matplotlib import pyplot as plt 
# 随机生成两组数组 
# 生成60个值在[0,50]内的数据 
num1 = np.random.randint(0,50,60) 
# 生成60个值在[200,250]内的数据 
num2 = np.random.randint(200,250,60) 
# 组合数据为num
num = np.hstack((num1, num2))
# 使用reshape函数将其转换为(120,1)  
num = num.reshape((120,1))  #每个数据为1列
# 转换为float32类型 
num = np.float32(num) 
# 调用kmeans模块 
# 设置参数criteria的值 
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) 
# 设置参数flags的值 
flags = cv2.KMEANS_RANDOM_CENTERS 
# 调用函数kmeans 
retval, bestLabels, centers = cv2.kmeans(num,2, None, criteria,10, flags) 

# 打印返回值 
print(retval) 
print(bestLabels) 
print(centers) 

# 获取分类结果 
n1 = num[bestLabels==0] 
n2 = num[bestLabels==1] 
    
# 绘制分类结果 
# 绘制原始数据 
plt.plot(np.ones(len(n1)),n1,'ro') 
plt.plot(np.ones(len(n2)),n2,'bo') 
# 绘制中心点 
#plt.plot([1],centers[0],'rx') 
#plt.plot([1],centers[1],'bx') 
plt.show() 
 

例2:

有两种物体:

  • 物体1的长和宽都在 [0,20] 内
  • 物体2的长和宽都在[40,60] 内

使用随机数模拟两种物体的长度和宽度,并使用函数cv2.kmeans()对它们分类。

根据题目要求,主要步骤如下:

  • 随机生成数据,并将它们转换为函数cv2.kmeans()可以处理的形式。
  • 设置函数cv2.kmeans()的参数形式。
  • 调用函数cv2.kmeans()。
  • 根据函数cv2.kmeans()的返回值,确定分类结果。
  • 绘制经过分类的数据及中心点,观察分类结果。
import numpy as np 
import cv2 
from matplotlib import pyplot as plt 
# 随机生成两组数值 
#长和宽都在[0,20]内 
m1 = np.random.randint(0,20, (30,2)) 
#长和宽的大小都在[40,60] 
m2 = np.random.randint(40,60, (30,2)) 
# 组合数据 
m = np.vstack((m1, m2)) 
# 转换为float32类型 
m = np.float32(m) 
# 调用kmeans模块 
# 设置参数criteria值 
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) 
# 调用kmeans函数 
ret, label, center=cv2.kmeans(m,2, None, criteria,10, cv2.KMEANS_RANDOM_CENTERS) 
    
''' 
#打印返回值 
print(ret) 
print(label) 
print(center) 
''' 
# 根据kmeans的处理结果,将数据分类,两大类 
res1 = m[label.ravel()==0] 
res2 = m[label.ravel()==1] 
# 绘制分类结果数据及中心点 
plt.scatter(res1[:,0], res1[:,1], c = 'g', marker = 's') 
plt.scatter(res2[:,0], res2[:,1], c = 'r', marker = 'o') 
plt.scatter(center[0,0], center[0,1], s = 200, c = 'b', marker = 'o') 
plt.scatter(center[1,0], center[1,1], s = 200, c = 'b', marker = 's') 
plt.xlabel('Height'), plt.ylabel('Width') 
plt.show() 

例3:

使用函数cv2.kmeans()将灰度图像处理为只有两个灰度级的二值图像。

需要对灰度图像内的色彩进行分类,将所有的像素点划分为两类。然后,用这两类的中心点像素值替代原有像素值,满足题目的要求。

主要步骤如下:

图像预处理

读取图像,并将图像转换为函数cv2.kmeans()可以处理的形式。

在读取图像时,如果是3个通道的RGB图像,需要将图像的RGB值处理为一个单独的特征值。具体实现时,用函数cv2.reshape()完成对图像特征值的调整。

为了满足函数cv2.kmeans()的要求,需要将图像的数据类型转换为numpy.float32类型。

设置函数cv2.kmeans()的参数形式

设置参数criteria的值为“(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)”,让函数cv2.kmeans()在达到一定精度或者达到一定迭代次数时,即停止迭代。

设置参数K的值为2,将所有像素划分为两类

调用函数cv2.kmeans()

调用函数cv2.kmeans(),得到距离值、分类中心点和分类标签,用于后续操作。

值替换

将像素点的值替换为当前分类的中心点的像素值。

显示变换前后的图像

分别显示原始图像和二值化图像。

import numpy as np
import cv2
import matplotlib.pyplot as plt
# 读取待处理图像
img = cv2.imread('./img/hand2.png')
# 使用reshape将一个像素点的RGB值作为一个单元处理
data = img.reshape((-1,3))    # n行 3列
# 转换为kmeans可以处理的类型
data = np.float32(data)
# 调用kmeans模块
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K =2
ret, label, center=cv2.kmeans(data, K, None, criteria,10, cv2.KMEANS_RANDOM_CENTERS) 

# 转换为uint8数据类型,将每个像素点都赋值为当前分类的中心点像素值
# 将center的值转换为uint8
center = np.uint8(center)
# 使用center内的值替换原像素点的值
res1 = center[label.flatten()]   # 根据索引来取值,最后结果的大小同索引的大小
# 使用reshape调整替换后的图像
res2 = res1.reshape((img.shape))
# 显示处理结果
plt.subplot(121)
plt.imshow(img[:,:,::-1])
plt.axis('off')
plt.subplot(122)
plt.imshow(res2[:,:,::-1])
plt.axis('off')
plt.show()

调整程序中的K值,就能改变图像的显示结果。例如,K=8,则可以让图像显示8个灰度级。

到此这篇关于python中opencv K均值聚类的实现示例的文章就介绍到这了,更多相关opencv K均值聚类内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python使用OpenCV和K-Means聚类对毕业照进行图像分割

    图像分割是将图像分割成多个不同区域(或片段)的过程.目标是将图像的表示变成更容易和更有意义的图像. 在这篇博客中,我们将看到一种图像分割方法,即K-Means Clustering. K-Means 聚类是一种无监督机器学习算法,旨在将N 个观测值划分为K 个聚类,其中每个观测值都属于具有最近均值的聚类.集群是指由于某些相似性而聚合在一起的数据点的集合.对于图像分割,这里的簇是不同的图像颜色. 我们使用的环境是pip install opencv-python numpy matplotlib

  • Python+OpenCV实战之利用 K-Means 聚类进行色彩量化

    目录 前言 利用 K-Means 聚类进行色彩量化 完整代码 显示色彩量化后的色彩分布 前言 K-Means 聚类算法的目标是将 n 个样本划分(聚类)为 K 个簇,在博文<OpenCV与机器学习的碰撞>中,我们已经学习利用 OpenCV 提供了 cv2.kmeans() 函数实现 K-Means 聚类算法,该算法通过找到簇的中心并将输入样本分组到簇周围,同时通过简单的示例了解了 K-Means 算法的用法.在本文中,我们将学习如何利用 K-Means 聚类进行色彩量化,以减少图像中颜色数量.

  • python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法

    python-opencv 中值滤波{cv2.medianBlur(src, ksize)} 中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 .与邻域平均法类似,但计算的是中值 #用中值法 for y in xrange(1,myh-1): for x in xrange(1,myw-1): lbimg[y,x]=np.median(tmpimg[y-1:y+2,x-1:x+2] 下面调用opencv的函数 # -*- coding: utf-8 -*- #c

  • OpenCV 图像分割实现Kmean聚类的示例代码

    目录 1 Kmean图像分割 2 流程 3 实现 1 Kmean图像分割 按照Kmean原理,对图像像素进行聚类.优点:此方法原理简单,效果显著.缺点:实践发现对于前景和背景颜色相近或者颜色区分度差的图像效果不显著.本文对图像进行滤波,主要是为了消除树枝颜色的影响(滤波为非Keman图像分割的必要操作). 2 流程 (1)读入图片,把图片转化为二维.(2)根据Kmean算法对图像分割,返回类别标签和各类别中心点.(3)根据类别标签复制各类别中心点得到结果,在对结果调整到原有尺度. 3 实现 (1

  • python中opencv K均值聚类的实现示例

    目录 K均值聚类 K均值聚类的基本步骤 K均值聚类模块 简单例子 K均值聚类 预测的是一个离散值时,做的工作就是“分类”. 预测的是一个连续值时,做的工作就是“回归”. 机器学习模型还可以将训练集中的数据划分为若干个组,每个组被称为一个“簇(cluster)”.这种学习方式被称为“聚类(clusting)”,它的重要特点是在学习过程中不需要用标签对训练样本进行标注.也就是说,学习过程能够根据现有训练集自动完成分类(聚类). 根据训练数据是否有标签,可以将学习划分为监督学习和无监督学习. K近邻.

  • python机器学习实战之K均值聚类

    本文实例为大家分享了python K均值聚类的具体代码,供大家参考,具体内容如下 #-*- coding:utf-8 -*- #!/usr/bin/python ''''' k Means K均值聚类 ''' # 测试 # K均值聚类 import kMeans as KM KM.kMeansTest() # 二分K均值聚类 import kMeans as KM KM.biKMeansTest() # 地理位置 二分K均值聚类 import kMeans as KM KM.clusterClu

  • K均值聚类算法的Java版实现代码示例

    1.简介 K均值聚类算法是先随机选取K个对象作为初始的聚类中心.然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心.聚类中心以及分配给它们的对象就代表一个聚类.一旦全部对象都被分配了,每个聚类的聚类中心会根据聚类中现有的对象被重新计算.这个过程将不断重复直到满足某个终止条件.终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小. 2.什么是聚类 聚类是一个将数据集中在某些方面相似的数据成员进行分类组织

  • 使用Python中OpenCV和深度学习进行全面嵌套边缘检测

    这篇博客将介绍如何使用OpenCV和深度学习应用全面嵌套的边缘检测.并将对图像和视频流应用全面嵌套边缘检测,然后将结果与OpenCV的标准Canny边缘检测器进行比较. 1. 效果图 愤怒的小鸟--原始图 VS Canny边缘检测图 VS HED边缘检测图 花朵--原始图 VS Canny边缘检测图 VS HED边缘检测图 视频效果图GIF 如下 2. 全面嵌套边缘检测与Canny边缘检测 2.1 Hed与Canny边缘检测对比 Holistically-Nested Edge Detectio

  • python中opencv实现图片文本倾斜校正

    本项目为python项目需要安装python及python的opencv模块:opencv_python-4.0.1-cp37-cp37m-win32.whl 和 python的矩阵运算模块:numpy. 1.第一步,安装python3.7,具体安装步骤略. 2.第二步,使用pip安装python的矩阵运算模块:numpy. python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose

  • Python中OpenCV实现简单车牌字符切割

    在Jupyter Notebook上使用Python+opencv实现如下简单车牌字符切割.关于opencv库的安装可以参考:Python下opencv库的安装过程与一些问题汇总. 1.实现代码 import cv2 import numpy as np import matplotlib.pyplot as plt from PIL import Image #读取原图片 image1=cv2.imread("123456.jpg") cv2.imshow("image1&

  • python中opencv图像叠加、图像融合、按位操作的具体实现

    目录 1图像叠加 2图像融合 3按位操作 1图像叠加 可以通过OpenCV函数cv.add()或简单地通过numpy操作添加两个图像,res = img1 + img2.两个图像应该具有相同的深度和类型,或者第二个图像可以是标量值. NOTE: OpenCV添加是饱和操作,也就是有上限值,而Numpy添加是模运算. 添加两个图像时, OpenCV功能将提供更好的结果.所以总是更好地坚持OpenCV功能. 代码: import cv2 import numpy as np x = np.uint8

  • python中opencv实现文字分割的实践

    图片文字分割的时候,常用的方法有两种.一种是投影法,适用于排版工整,字间距行间距比较宽裕的图像:还有一种是用OpenCV的轮廓检测,适用于文字不规则排列的图像. 投影法 对文字图片作横向和纵向投影,即通过统计出每一行像素个数,和每一列像素个数,来分割文字. 分别在水平和垂直方向对预处理(二值化)的图像某一种像素进行统计,对于二值化图像非黑即白,我们通过对其中的白点或者黑点进行统计,根据统计结果就可以判断出每一行的上下边界以及每一列的左右边界,从而实现分割的目的. 算法步骤: 使用水平投影和垂直投

  • Python中OpenCV图像特征和harris角点检测

    目录 概念 第一步:计算一个梯度 Ix,Iy 第二步:整合矩阵,计算特征值 第三步:比较特征值的大小 第四步: 非极大值抑制,把真正的角点留下来,角点周围的过滤掉 代码实现 概念 第一步:计算一个梯度 Ix,Iy 第二步:整合矩阵,计算特征值 第三步:比较特征值的大小 第四步: 非极大值抑制,把真正的角点留下来,角点周围的过滤掉 代码实现 import cv2 import numpy as np img =cv2.imread('pie.png') print('img.shape',img.

随机推荐