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) ...
随机推荐
- 【python】正则表达式-group和group的区别
__author__ = 'paul' import re a = "123abc456" print re.search("([0-9]*)([a-z]*)([0-9] ...
- js将UTC时间转化为当地时区时间
js将UTC时间转化为当地时区时间(UTC转GMT) 我们在进行网站开发的时候有可能会涉及到国外的用户或者用户身在国外,这时就会存在时差问题,比如说我们在中国的时间是08:00,但是此时韩国的时间 ...
- 【Codeforces】CF 165 E Compatible Numbers(状压dp)
题目 传送门:QWQ 分析 很难想到方向,但有方向了就很easy了. 我们如何减少不必要的计算? 如果我们知道了$ 100111 $的相容的数,$ 100101 $的相容数和他是完全一样的. 我们就靠 ...
- Thread 1 cannot allocate new log的问题分析 (转载)
Thread 1 cannot allocate new log的问题分析 发生oracle宕机事故,alert文件中报告如下错误: Fri Jan 12 04:07:49 2007Thread 1 ...
- mysql 笔记分享
mysql LPAD 和RPAD不足位数补齐填充函数总结一下mysql数据库的一些特征MySQL WHERE 语句优化之我见mysql limit 实例详解mysql 如何实现多表联合更新MySQL ...
- Python print函数参数详解
官方文档 print(…) print(value, …, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False) Prints the valu ...
- 深度强化学习——连续动作控制DDPG、NAF
一.存在的问题 DQN是一个面向离散控制的算法,即输出的动作是离散的.对应到Atari 游戏中,只需要几个离散的键盘或手柄按键进行控制. 然而在实际中,控制问题则是连续的,高维的,比如一个具有6个关节 ...
- css3选择符
常用的选择符 1.元素选择符 2.id选择符 3.class选择符 4.通配符 5.群组选择符 6.包含选择符 7.伪类选择符(伪类选择符CSS中已经定义好的选择器,不能随便取名) 8.伪对象选择符( ...
- Visual Studio自动添加头部注释
VS2013 自动添加头部注释 1.找到VS2013的安装目录 下文以安装目录 C:\Program Files (x86)\Microsoft Visual Studio 12.0 为例 2.修改C ...
- collections模块---(namedtuple、deque、OrderdDict、defaultdict、Counter)和configparser模块
在内置数据类型(dict. list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter. deque.defaultdict.namedtuple 和 ...