主导颜色
使用CIE LAB颜色空间和k-means聚类算法寻找图像的主导颜色。
算法
颜色空间
RGB颜色空间没有考虑到人类的感知,所以使用CIELAB颜色空间,它旨在模拟人类视觉 [1]。
RGB转换
从RGB值转换为LAB值,首先需要将RGB值转换为类似sRGB这样的绝对颜色空间[2]。在iOS上,这一转换是多余的,因为sRGB就是设备的原生颜色空间[3]。在OS X上,可以使用-[NSColorSpace sRGBColorSpace]
方法来进行转换。
将颜色转换为sRGB后,首先转换为线性的sRGB值,然后转换为CIE XYZ值[4]。最后,使用D65标准光源[6][7]将其转换为CIE LAB颜色空间[5]。
颜色差异
使用颜色差异算法来分组相似的色彩。API用户可以选择CIE 76[8]、CIE 94[9]和CIE 2000[10]算法,分别用于低、中、高色彩分组精度。默认算法是CIE 94,因为它提供的结果与CIE 2000相似,且与CIE 76相比性能影响微小。
聚类(k-means)
使用标准的k-means聚类算法[11][12][13]将像素分组到以主要色彩为特色的集群中。
选择K值
最初选择k值是基于经验规则 k = sqrt(n/2)
[14],但这种选择导致在较大的n值下,k值太大以至于无法在合理时间内运行。目前,我使用一个神秘的值16
,因为经验测试表明,对于许多不同的图像,它产生了最佳结果,但我仍在探索多种基于数据的替代方法。
选择初始质心
目前,初始质心是随机选择的。另一种方法是使用适用于k-means++算法,其中首先随机选择了第一个质心,接下来根据距离随机选中质心的距离成比例选择质心。
降采样
k-means算法在最坏情况下的运行时间是输入大小的超多项式,[15],所以采样大量像素是一个问题。图像会自动降采样,以使得像素总数不超过指定的最大像素数。我所使用的值是1000
,在准确结果和运行时间之间找到一个好的平衡。
实现
除了解码颜色空间之间的函数外,所有内容都在Swift中实现。这些函数使用了GLKit,因此必须用C编写(因为Swift目前不支持C联合)。
应用
该项目包含Mac和iOS应用,可用于查看算法的结果和运行简单的基准测试。
联系方式
- Indragie Karunaratne
- @indragie
- http://indragie.com
许可证
根据MIT许可证授权。
参考
1 http://en.wikipedia.org/wiki/Lab_color_space#Advantages
2 http://en.wikipedia.org/wiki/Lab_color_space#RGB_and_CMYK_conversions
3 https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGColorSpace/index.html
4 http://en.wikipedia.org/wiki/SRGB#The_forward_transformation_.28CIE_xyY_or_CIE_XYZ_to_sRGB.29
5 http://en.wikipedia.org/wiki/Lab_color_space#CIELAB-CIEXYZ_conversions
6 http://en.wikipedia.org/wiki/Illuminant_D65
7 http://www.easyrgb.com/index.php?X=MATH&H=15#text15
8 http://en.wikipedia.org/wiki/Color_difference#CIE76
9 http://en.wikipedia.org/wiki/Color_difference#CIEDE2000
10 http://en.wikipedia.org/wiki/Color_difference#CIEDE2000
11 http://en.wikipedia.org/wiki/K-means_clustering
12 http://users.eecs.northwestern.edu/~wkliao/Kmeans/
13 http://cs.smu.ca/~r_zhang/code/kmeans.c
14 http://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set#cite_note-1
15 http://en.wikipedia.org/wiki/K-means%2B%2B