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

matlab中k-means算法_OpenCV图像处理-KMeans 图像处理

KMeans 数据分类

概述

  • KMeans算法的作者是MacQueen, KMeans的算法是对数据进行分类的算法,采用的硬分类方式,是属于非监督学习的算法;
  • 对于给定的样本集,按照样本之间的距离大小,将样本划分为K个簇,让簇内的点尽量紧密的连接在一起,而让簇间的距离尽量的大。

KMeans算法

输入:训练数据集

,聚类簇数 k;

过程:函数

.

1:从 D 中随机选择 k 个样本作为初始“簇中心”向量:

:

2:repeat

3: 令

4: for

do

5: 计算样本

与各“簇中心”向量
的欧式距离

6: 根据距离最近的“簇中心”向量确定

的簇标记:

7: 将样本

划入相应的簇:
;

8: end for

9: for

do

10: 计算新“簇中心”向量:

;

11: if

then

12: 将当前“簇中心”向量

更新为

13: else

14: 保持当前均值向量不变

15: end if

16: end for

17: else

18:until 当前“簇中心”向量均未更新

输出:簇划分

备注:

kmeans算法由于初始“簇中心”点是随机选取的,因此最终求得的簇的划分与随机选取的“簇中心”有关,也就是说,可能会造成多种 k 个簇的划分情况。
这是因为kmeans算法收敛到了局部最小值,而非全局最小值。

二分KMeans

  • 基于kmeans算法容易使得结果为局部最小值而非全局最小值这一缺陷,对算法加以改进。
  • 使用一种用于度量聚类效果的指标SSE(Sum of Squared Error),即对于第 i 个簇,其SSE为各个样本点到“簇中心”点的距离的平方的和,SSE值越小表示数据点越接近于它们的“簇中心”点,聚类效果也就越好,以此作为划分簇的标准。

算法思想: 先将整个样本集作为一个簇,该“簇中心”点向量为所有样本点的均值,计算此时的SSE。若此时簇个数小于 k ,对每一个簇进行kmeans聚类(k=2) ,计算将每一个簇一分为二后的总误差SSE,选择SSE最小的那个簇进行划分操作。

输入: 训练数据集

,聚类簇数
k ;

过程: 函数

.

1: 将所有点看做一个簇,计算此时“簇中心”向量:

2:while

3: for

do

4: 将第

个簇使用 kmeans算法进行划分,其中

5: 计算划分后的误差平方和

6: 比较

种划分的SSE值,选择SSE值最小的那种簇划分进行划分

7: 更新簇的分配结果

8: 添加新的“簇中心”

9:until 当前“簇中心”个数达到

输出: 簇划分

Opnecv 函数

OpenCV中KMeans数据分类的API为:

cv2.kmeans(
    InputArray data,
    int K,
    InputOutputArray bestLabels,
    TermCriteria criteria,
    int attempts,
    int flags,
    OutputArray centers = noArray() 
)
输入:
  • data表示输入的样本数据,必须是按行组织样本,每一行为一个样本数据,列表示样本的维度;
  • K表示最终的分类数目;
  • bestLabels 表示最终分类每个样本的标签;
  • criteria 表示KMeans分割的停止条件;
  • attempts 表示采样不同初始化标签尝试次数;
  • flag表示中心初始化方法:
    • KMEANS_RANDOM_CENTERS
    • KMEANS_PP_CENTERS
    • KMEANS_USE_INITIAL_LABELS
  • centers表示最终分割以后的每个cluster的中心位置。

代码示例

import numpy as np
import cv2
from matplotlib import pyplot as plt

# 读取数据
def loadDataSet(fileName):
    data = []
    with open(fileName) as f:
        for line in f.readlines():
            curLine = line.strip().split("t")
            fltLine = list(map(float, curLine))  # 转换为float
            data.append(fltLine)
    return np.array(data, dtype=np.float32)

# 导入数据
data = loadDataSet('testSet2.txt')

# 定义停止条件
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

# kmeans计算
ret,label,center=cv2.kmeans(data, 3, None, criteria, 2, cv2.KMEANS_RANDOM_CENTERS)

print(len(label))
print(center)

# 获取不同标签的点
A = data[label.ravel()==0]
B = data[label.ravel()==1]
C = data[label.ravel()==2]

# 可视化
plt.scatter(A[:,0],A[:,1])
plt.scatter(B[:,0],B[:,1],c = 'r')
plt.scatter(C[:,0],C[:,1],c = 'purple')
plt.scatter(center[:,0],center[:,1],s = 80,c = 'black', marker = '*')
plt.xlabel('Height'),plt.ylabel('Weight')
plt.show()

b08c7a124e7e24071ac5f4942eea756f.png
KMeans 结果

Kmeans图像分割

✔️ 在一张图片中,每一个像素点对应位置坐标和色彩坐标,用k-means算法对图像聚类不是聚类位置信息,而是对其色彩进行聚类。

✔️ kmeans能够实现简单的分割,当然效果不是非常好,需要经过一些后处理调整,才能得到高精度的分割图。

颜色空间分割

这里我们选取一个半身像,针对图片的颜色进行kmeans分割。

import numpy as np
import cv2 as cv

image = cv.imread('people.jpg')

# 构建图像数据
data = image.reshape((-1,3))
data = np.float32(data)

# MAX_ITER最大迭代次数,EPS最高精度
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
num_clusters = 4
ret,label,center=cv.kmeans(data, num_clusters, None, criteria, num_clusters, cv.KMEANS_RANDOM_CENTERS)

center = np.uint8(center)

# 颜色label
color = np.uint8([[255, 0, 0],
                  [0, 0, 255],
                  [128, 128, 128],
                  [0, 255, 0]])

res = color[label.flatten()]
print(res.shape)
# 显示
result = res.reshape((image.shape))
cv.imshow('kmeans-image-demo',result)
cv.waitKey(0)
cv.destroyAllWindows()

dcfe3048cb437a58588f78c35e2285e2.png
KMeans 分割

背景替换

✔️ KMeans可以实现简单的证件照片的背景分割提取与替换,大致可以分为如下几步实现:

  1. 读入图像建立KMenas样本;
  2. 使用KMeans图像分割,指定指定分类数目;
  3. 取左上角的label得到背景cluster index;
  4. 生成alpha图,然后选取新背景进行合成。
import numpy as np
import cv2 as cv

image = cv.imread('people.jpg')
cv.imshow("input", image)
h, w ,ch = image.shape
# 构建图像数据
data = image.reshape((-1,3))
data = np.float32(data)

# 图像分割
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
num_clusters = 4
ret,label,center=cv.kmeans(data, num_clusters, None, criteria, num_clusters, cv.KMEANS_RANDOM_CENTERS)

# 生成mask区域
index = label[0][0]
center = np.uint8(center)
color = center[0]
mask = np.ones((h, w), dtype=np.uint8)*255.
label = np.reshape(label, (h, w))
# alpha图
mask[label == index] = 0

# 高斯模糊
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
# 膨胀,防止背景出现
cv.erode(mask, se, mask)
#边缘模糊
mask = cv.GaussianBlur(mask, (5, 5), 0)
cv.imshow('alpha-image',mask)

# 白色背景
bg = np.ones(image.shape, dtype=np.float)*255.

# 粉丝背景
purle = np.array([255, 0, 255])
bg_color = np.tile(purle, (image.shape[0], image.shape[1], 1))

alpha = mask.astype(np.float32) / 255.
fg = alpha[..., None] * image
new_image = fg + (1 - alpha[..., None])*bg
new_image_purle = fg + (1 - alpha[..., None])*bg_color

cv.imwrite("white.jpg", np.hstack((image, new_image.astype(np.uint8))))
cv.imwrite("purle.jpg", np.hstack((image, new_image_purle.astype(np.uint8))))
cv.waitKey(0)
cv.destroyAllWindows()

4a87b75862711cc5ea334fe1782c01fe.png
转换白底

d865e3d53c5fae8391223c6228dc5d70.png
转换粉底

主色彩提取

✔️ KMeans分割会计算出每个聚类的像素平均值,根据这个可以得到图像的主色彩RGB分布成分多少,得到各种色彩在图像中的比重,绘制出图像对应的取色卡!

这个方面在纺织与填色方面特别有用!主要步骤显示如下:

  1. 读入图像建立KMenas样本
  2. 使用KMeans图像分割,指定分类数目
  3. 统计各个聚类占总像素比率,根据比率建立色卡!
import numpy as np
import cv2 as cv

image = cv.imread('yuner.jpg')

cv.imshow("input", image)
h, w ,ch = image.shape
# 构建图像数据
data = image.reshape((-1,3))
data = np.float32(data)

# 图像分割
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
num_clusters = 5
ret,label,center=cv.kmeans(data, num_clusters, None, criteria, num_clusters, cv.KMEANS_RANDOM_CENTERS)
print(label[300])

# 生成主色彩条形卡片
card = np.zeros((50, w, 3), dtype=np.uint8)
clusters = np.zeros([5], dtype=np.int32)
# 统计每一类的数目
for i in range(len(label)):
    clusters[label[i]] += 1
# 比重
clusters = np.float32(clusters) / float(h*w)
center = np.int32(center)
x_offset = 0

# 绘制色卡
for c in range(num_clusters):
    dx = np.int(clusters[c] * w)
    b = center[c][0]
    g = center[c][1]
    r = center[c][2]
    cv.rectangle(card, (x_offset, 0), (x_offset+dx, 50), (int(b), int(g), int(r)), -1)
    x_offset += dx

cv.imshow("color table", card)
cv.waitKey(0)
cv.destroyAllWindows()

b500588fe19ac3ae882e88f2a5ef4c9b.png
Color_Card1

f73e5838446cb8d6daec8fdf559c2460.png
Color_Card2

------------------------------------------可爱の分割线------------------------------------------

更多Opencv教程可以 Follow github的opencv教程,中文&English 欢迎Star❤️❤️❤️

JimmyHHua/opencv_tutorials​github.com
7d58786e2884a76db0558c0df1c35f26.png

参考

- kmeans算法理解及代码实现

相关文章:

  • python中的转义字符是什么意思_python 转义字符、运算符、列表。。。。
  • python发微信公众号消息_个人微信公众号搭建Python实现 -接收和发送消息-基本说明与实现(14.2.1)...
  • python爬虫代写价格_python爬取京东价格
  • lua get reused time_利用redis-lua+python实现接口限流
  • server2008网卡驱动包_网卡工作原理详解
  • svpwm的原理及法则推导和控制算法详解_电机控制要点解疑:SPWM,SVPWM和矢量控制...
  • python删除文件指定字符串,从Python中的字符串中删除特定字符
  • python基础读后感_《python基础教程 》第一章 读书笔记
  • 二叉树的字符图形显示程序_(CSPJ)入门级C++语言试题A卷答案解析阅读程序
  • 服务器显示地址正在使用_用Windows Storage Server 2008做iSCSI存储服务器
  • 权限设计表结构超详细_超详细!!五金模具组件及工程结构设计
  • flex 下对齐_开启 flex 与 grid 布局方式之旅
  • python中的and or的区别_Python 中 (,|)和(and,or)之间的区别
  • python csv模块dictwrite_Pythoncsv.DictWriterwriterow()返回
  • dataset__getitem___PyTorch 之Dataset和DataLoader
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • 2019.2.20 c++ 知识梳理
  • Android开源项目规范总结
  • ES6--对象的扩展
  • Linux下的乱码问题
  • nginx 配置多 域名 + 多 https
  • NSTimer学习笔记
  • PHP那些事儿
  • Python_网络编程
  • Service Worker
  • WePY 在小程序性能调优上做出的探究
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 服务器从安装到部署全过程(二)
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 前端面试之闭包
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 为什么要用IPython/Jupyter?
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 怎样选择前端框架
  • Spring第一个helloWorld
  • 阿里云ACE认证学习知识点梳理
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (39)STM32——FLASH闪存
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (Matlab)使用竞争神经网络实现数据聚类
  • (rabbitmq的高级特性)消息可靠性
  • (TOJ2804)Even? Odd?
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (三)终结任务
  • (五)关系数据库标准语言SQL
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转) ns2/nam与nam实现相关的文件
  • (转)c++ std::pair 与 std::make
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • (转载)PyTorch代码规范最佳实践和样式指南