机器学习在图像识别方面具有很好的效果,今天在网易云课堂黑板可老师视频中学习了一下Kmeans算法,是一种非监督类学习算法,具体步骤如下
1,选取K个点作为初始中心
2,将每个点最近的中心,形成K个簇
3,重新计算每个簇的中心
4,如果簇中心发生明显的变化或者未达到最大迭代次数,则返回到第二部
如上图,有很多点,需要将这些点分成类簇,我们的方法是
1,先随机选择三个点Cluster
2,判断所有点距离这三个点的距离,并将点加入到该Cluster中
3,重新计算每个簇的中心
4,迭代2
下面讲一个实际的问题,对于一张图片,我们想找出图片的K个主要色彩,然后将图片换成包含主要色彩的图片
具体步骤如下:
1,将一个图片转化成像素集合
2,随机在这些像素集合中选取K个点,也就是三个簇
3,计算每个像素点距离这三个簇最近的簇,并把它放入该簇中
4,第三步形成了新的簇,然后计算新簇的中心,计算簇中心的方法是求每个簇的RGB三原色的平均颜色,根据平均颜色选取新的pixel,也就是簇的中心
5,重复步骤2至迭代次数
6,迭代完成后得到图片的中心pixel
7,遍历原图的每个pixel,求出距离该pixel最近的中心pixel,记为pixelCenter并将原图的pixel置换为pixelCenter
8,7步骤完成后得到新的图片
Python示例代码如下,(从github上down的)
# -*- coding: utf-8 -*- # https://github.com/ZeevG/python-dominant-image-colour # commented by heibanke from PIL import Image import random import numpy class Cluster(object): """ pixels: 主要颜色所依据的像素点 centroid: 主要颜色的RGB值 """ def __init__(self): self.pixels = [] self.centroid = None def addPoint(self, pixel): self.pixels.append(pixel) def setNewCentroid(self): """ 通过pixels均值重新计算主要颜色 """ R = [colour[0] for colour in self.pixels] G = [colour[1] for colour in self.pixels] B = [colour[2] for colour in self.pixels] R = sum(R) / len(R) G = sum(G) / len(G) B = sum(B) / len(B) self.centroid = (R, G, B) self.pixels = [] return self.centroid class Kmeans(object): def __init__(self, k=3, max_iterations=5, min_distance=5.0, size=400): """ k: 主要颜色的分类个数 max_iterations: 最大迭代次数 min_distance: 当新的颜色和老颜色的距离小于该最小距离时,提前终止迭代 size: 用于计算的图像大小 """ self.k = k self.max_iterations = max_iterations self.min_distance = min_distance self.size = (size, size) def run(self, image): self.image = image #生成缩略图,节省运算量 self.image.thumbnail(self.size) self.pixels = numpy.array(image.getdata(), dtype=numpy.uint8) self.clusters = [None]*self.k self.oldClusters = None #在图像中随机选择k个像素作为初始主要颜色 randomPixels = random.sample(self.pixels, self.k) for idx in range(self.k): self.clusters[idx] = Cluster() self.clusters[idx].centroid = randomPixels[idx] iterations = 0 #开始迭代 while self.shouldExit(iterations) is False: self.oldClusters = [cluster.centroid for cluster in self.clusters] print iterations #对pixel和self.clusters中的主要颜色分别计算距离,将pixel加入到离它最近的主要颜色所在的cluster中 for pixel in self.pixels: self.assignClusters(pixel) #对每个cluster中的pixels,重新计算新的主要颜色 for cluster in self.clusters: cluster.setNewCentroid() iterations += 1 return [cluster.centroid for cluster in self.clusters] def assignClusters(self, pixel): shortest = float('Inf') for cluster in self.clusters: distance = self.calcDistance(cluster.centroid, pixel) if distance < shortest: shortest = distance nearest = cluster nearest.addPoint(pixel) def calcDistance(self, a, b): result = numpy.sqrt(sum((a - b) ** 2)) return result def shouldExit(self, iterations): if self.oldClusters is None: return False #计算新的中心和老的中心之间的距离 for idx in range(self.k): dist = self.calcDistance( numpy.array(self.clusters[idx].centroid), numpy.array(self.oldClusters[idx]) ) if dist < self.min_distance: return True if iterations <= self.max_iterations: return False return True # The remaining methods are used for debugging def showImage(self): """ 显示原始图像 """ self.image.show() def showCentroidColours(self): """ 显示主要颜色 """ for cluster in self.clusters: image = Image.new("RGB", (200, 200), cluster.centroid) image.show() def showClustering(self): """ 将原始图像的像素完全替换为主要颜色后的效果 """ localPixels = [None] * len(self.image.getdata()) for idx, pixel in enumerate(self.pixels): shortest = float('Inf') for cluster in self.clusters: distance = self.calcDistance( cluster.centroid, pixel ) if distance < shortest: shortest = distance nearest = cluster localPixels[idx] = nearest.centroid w, h = self.image.size localPixels = numpy.asarray(localPixels)\ .astype('uint8')\ .reshape((h, w, 3)) colourMap = Image.fromarray(localPixels) return colourMap if __name__=="__main__": from PIL import Image import os k_image=Kmeans(k=3) #默认参数 path = './ml_kmean.pypics/' fp = open('file_color.txt','w') for filename in os.listdir(path): print path+filename try: color = k_image.run(Image.open(path+filename)) w_image = k_image.showClustering() w_image.save(path+'mean_'+filename,'jpeg') fp.write('The color of '+filename+' is '+str(color)+'\n') except : print "This file format is not support" fp.close()
原图和处理之后的图对比如下:
相关推荐
机器学习算法 机器学习算法之KMeans聚类算法实现
Python数据分析与机器学习-使用Kmeans进行图像压缩 Python数据分析与机器学习-使用Kmeans进行图像压缩
机器学习中kmeans的实现,其中包含对kmeans的改进,二分kmeans的实现,内含语料,下载后可运行
机器学习关于Kmeans的实验报告,内含代码,实验是关于鹦鹉图片颜色聚类
python机器学习 聚类算法Kmeans代码实现 包含所用数据集和代码 适合新手
ai ai_机器学习算法实现之KMeans聚类
机器学习中,kmean算法是应用非常广泛的一个算法,本文档推举除一些应用案例。
北邮+机器学习+自动化+yhh+机器学习实验+作业+Kmeans算法+大家都懂的,作业居多的老师,创作不易
此代码包含机器学习kmeans算法对K值的评估,可以直观看到K的不同对应的准则值的不同
01-机器学习_(python数据类型详解) ...04-机器学习_(kmeans聚类算法与应用) 05-机器学习_(协同过滤推荐算法与应用) 06-机器学习_(决策树分类算法与应用) 07-机器学习_(lineage回归分类算法与应用)
机器学习算法 机器学习算法之使用Python实现KMeans算法
k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”...
spark机器学习,Scala语言开发,能够实现Kmeans聚类。
【机器学习项目实战】Python实现聚类(Kmeans)分析客户分组 资料说明:包括数据集+源代码+Word文档说明。 资料内容包括: 1)问题定义; 2)数据收集; 3)数预处理; 4)探索性数据分析; 5)聚类模型; 6)聚类可视化...
机器学习C++源码解析-kmeans算法-源码+数据
根据网上资源自己整理的C++代码,代码有注释,结构清晰易读,有测试代码,带测试数据。并附带可执行程序,你值得拥有。自己也可轻易建工程运行,不依赖任何第三方库。
Spark中机器学期(Machine Learning)之KMeans算法完整代码讲解
机器学习:基于UCI葡萄酒数据集进行葡萄酒分类及产地预测(含源码+数据集文件) 源码是matlab的、源码是matlab的、源码是matlab的。重要事情说三遍!!! 共包含178组样本数据,来源于三个葡萄酒产地,每组数据包含...
利用C++结合OpenCV实现Kmeans聚类图像分割,需要配置OpenCV340版本,其他版本需要更改属性表。
跟着Leo机器学习实战:Kmeans聚类 Kmeans聚类 优点:容易实现 缺点:容易陷入局部最小值,在大规模数据收敛很慢。 适用数据类型:数值型数据 伪代码 加载数据 from numpy import * def loadDataSet(fileName): #...