k-means处理图片
问题描述:把给定图片,用图片中最主要的三种颜色来表示该图片
k-means思想:
1、选择k个点作为初始中心
2、将每个点指派到最近的中心,形成k个簇cluster
3、重新计算每个簇的中心
4、如果簇中心发生明显变化或未达到最大迭代次数,则回到step2
问题:初始点不对的时候,容易收敛到局部最优值
解决办法:
1、选择k个点作为初始中心——canopy,模拟退火,贝叶斯准则
2、将每个点指派到最近的中心,形成k个簇cluster
3、重新计算每个簇的中心
4、如果簇中心发生了明显的变化或未达到最大迭代次数,则回到step2
例子:给你一幅图像,找出其中最主要的三种颜色,并将图片用三种最主要的颜色表示出来
# -*- 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
#cluster有两个属性,centroid表示聚类中心,pixels表示依附于该聚类中心的那些像素点
#每个聚类中心都是一个单独的Cluster对象
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()#生成idx个Cluster的对象
self.clusters[idx].centroid = randomPixels[idx]#每个centroid是随机采样得到的 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实际上是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()) #enumerate用于既需要遍历元素下边也需要得到元素值的情况,用for循环比较麻烦
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 = './pics/'
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 = k_image.showCentroidColours()
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()
处理前的图片:

处理后的图片:

参考:http://blog.zeevgilovitz.com/detecting-dominant-colours-in-python/
k-means处理图片的更多相关文章
- KNN 与 K - Means 算法比较
KNN K-Means 1.分类算法 聚类算法 2.监督学习 非监督学习 3.数据类型:喂给它的数据集是带label的数据,已经是完全正确的数据 喂给它的数据集是无label的数据,是杂乱无章的,经过 ...
- 软件——机器学习与Python,聚类,K——means
K-means是一种聚类算法: 这里运用k-means进行31个城市的分类 城市的数据保存在city.txt文件中,内容如下: BJ,2959.19,730.79,749.41,513.34,467. ...
- 快速查找无序数组中的第K大数?
1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN).在此,我们想探索是否存在时间复杂度 < O(NlgN),而且近似等于O(N)的高 ...
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- numpy.ones_like(a, dtype=None, order='K', subok=True)返回和原矩阵一样形状的1矩阵
Return an array of ones with the same shape and type as a given array. Parameters: a : array_like Th ...
- 当我们在谈论kmeans(2)
本稿为初稿,后续可能还会修改:如果转载,请务必保留源地址,非常感谢! 博客园:http://www.cnblogs.com/data-miner/ 其他:建设中- 当我们在谈论kmeans(2 ...
- scikit-learn包的学习资料
http://scikit-learn.org/stable/modules/clustering.html#k-means http://my.oschina.net/u/175377/blog/8 ...
- HDU 3584 Cube (三维 树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3584 Cube Problem Description Given an N*N*N cube A, ...
- Torch7学习笔记(二)nn Package
神经网络Package [目前还属于草稿版,等我整个学习玩以后会重新整理] 模块Module module定义了训练神经网络需要的所有基础方法,并且是可以序列化的抽象类. module有两种状态变量: ...
- 2016中国大学生程序设计竞赛 - 网络选拔赛 J. Alice and Bob
Alice and Bob Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
随机推荐
- RequiresAuthentication
@RequiresAuthentication 验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时. @RequiresUser 验证用户是否被记忆,us ...
- Mac 下安装python3.7 + pip 利用 chrome + chromedriver + selenium 自动打开网页并自动点击访问指定页面
1.安装python3.7https://www.python.org/downloads/release/python-370/选择了这个版本,直接默认下一步 2.安装pipcurl https:/ ...
- Linux下Oracle中SqlPlus时上下左右键乱码问题的解决办法
window下的sqlplus可以通过箭头键,来回看历史命令,用起来非常的方便. 但是在Linux下,会出现各种乱码,非常不方便,如下图所示,每次打错一个字符就需要重新打一遍. 解决办法:rlwrap ...
- Mycat 数据库分库分表中间件
http://www.mycat.io/ Mycat 国内最活跃的.性能最好的开源数据库中间件! 我们致力于开发高性能的开源中间件而努力! 实体书Mycat权威指南 »开源投票支持Mycat下载 »s ...
- FPGA将加速今日新型态数据中心的主流应用
在这个强调智能与联网的时代,可编程逻辑栅阵列 (FPGA)已经成为一个重要且不可或缺的元件.以全球500亿个联网设备,一年所产生的数据量将不计其数.从数据中心.5G通讯.虚拟网络功能,到嵌入式系统,F ...
- 软件-分布式:Kylin (apache开源分布式分析引擎软件)
ylbtech-软件-分布式:Kylin (apache开源分布式分析引擎软件) Apache Kylin™是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以 ...
- 制作jQuery文字提示插件
(functions($){ $.fn.colorTip=function(settings){ var defaultSettings={ color:'yellow', timeout:500 } ...
- Python 天气预报+微信
""" Description: 需要提供以下三个信息,在申请到的微信企业号当中可以找到 agentid corpid corpsecret Author:Nod Dat ...
- 将ESXI所有的端口组迁移到分布式交换机的步骤
1.如果是DELL服务器,一般有2-4个网口,那么所有的网口都把网线插到交换机上:2.DELL安装ESXI系统,根据不同的DELL硬件,要安装不同的ESXI版本.原则上越高版本,支持的硬件越多向下兼容 ...
- [UE4]C++代码操作SplineMesh
转自:http://aigo.iteye.com/blog/2279503 void ARaceSpline::OnConstruction(const FTransform& Transfo ...