新的iTunes 11可以很好地查看专辑的歌曲列表,选择专辑封面功能的字体和背景颜色。有人想出算法是如何工作的吗?
答案 0 :(得分:422)
我将Mathematica中的iTunes 11颜色算法近似为专辑封面输入:
通过反复试验,我提出了一种算法,该算法适用于我测试过的约80%的专辑。
该算法的大部分涉及寻找图像的主色。然而,找到主色的先决条件是计算两种颜色之间的可量化差异。计算两种颜色之间差异的一种方法是计算RGB颜色空间中的欧几里德距离。然而,人类的色彩感知与RGB色彩空间中的距离并不匹配。
因此,我编写了一个函数来将RGB颜色(格式为{1,1,1}
)转换为YUV,这是一种颜色空间,可以更接近颜色感知:
(编辑:@cormullion和@Drake指出Mathematica内置的CIELAB和CIELUV颜色空间也是合适的...看起来我重新发明了轮子这里有点)
convertToYUV[rawRGB_] :=
Module[{yuv},
yuv = {{0.299, 0.587, 0.114}, {-0.14713, -0.28886, 0.436},
{0.615, -0.51499, -0.10001}};
yuv . rawRGB
]
接下来,我写了一个用上面的转换计算颜色距离的函数:
ColorDistance[rawRGB1_, rawRGB2_] :=
EuclideanDistance[convertToYUV @ rawRGB1, convertToYUV @ rawRGB2]
我很快发现内置的Mathematica函数DominantColors
不允许足够的细粒度控制来近似iTunes使用的算法。我写了自己的函数......
计算一组像素中主色的一种简单方法是将所有像素收集到相似颜色的桶中,然后找到最大的桶。
DominantColorSimple[pixelArray_] :=
Module[{buckets},
buckets = Gather[pixelArray, ColorDistance[#1,#2] < .1 &];
buckets = Sort[buckets, Length[#1] > Length[#2] &];
RGBColor @@ Mean @ First @ buckets
]
请注意,.1
是不同颜色必须分开考虑的容差。另请注意,虽然输入是原始三元组形式的像素数组({{1,1,1},{0,0,0}}
),但我返回一个Mathematica RGBColor
元素以更好地逼近内置DominantColors
函数。
我的实际功能DominantColorsNew
添加了在过滤掉给定的其他颜色后返回n
主色的选项。它还公开了每种颜色比较的公差:
DominantColorsNew[pixelArray_, threshold_: .1, n_: 1,
numThreshold_: .2, filterColor_: 0, filterThreshold_: .5] :=
Module[
{buckets, color, previous, output},
buckets = Gather[pixelArray, ColorDistance[#1, #2] < threshold &];
If[filterColor =!= 0,
buckets =
Select[buckets,
ColorDistance[ Mean[#1], filterColor] > filterThreshold &]];
buckets = Sort[buckets, Length[#1] > Length[#2] &];
If[Length @ buckets == 0, Return[{}]];
color = Mean @ First @ buckets;
buckets = Drop[buckets, 1];
output = List[RGBColor @@ color];
previous = color;
Do[
If[Length @ buckets == 0, Return[output]];
While[
ColorDistance[(color = Mean @ First @ buckets), previous] <
numThreshold,
If[Length @ buckets != 0, buckets = Drop[buckets, 1],
Return[output]]
];
output = Append[output, RGBColor @@ color];
previous = color,
{i, n - 1}
];
output
]
首先,我调整了专辑封面的大小(36px
,36px
)&amp;使用双边滤波器减少细节
image = Import["http://i.imgur.com/z2t8y.jpg"]
thumb = ImageResize[ image, 36, Resampling -> "Nearest"];
thumb = BilateralFilter[thumb, 1, .2, MaxIterations -> 2];
iTunes通过查找相册边缘的主色来选择背景色。但是,它会通过裁剪图像来忽略窄的专辑封面边框。
thumb = ImageCrop[thumb, 34];
接下来,我在图像的最外边缘找到了主色(带有上面的新功能),默认容差为.1
。
border = Flatten[
Join[ImageData[thumb][[1 ;; 34 ;; 33]] ,
Transpose @ ImageData[thumb][[All, 1 ;; 34 ;; 33]]], 1];
background = DominantColorsNew[border][[1]];
最后,我在整个图像中返回了两种主色,告诉函数也过滤掉了背景色。
highlights = DominantColorsNew[Flatten[ImageData[thumb], 1], .1, 2, .2,
List @@ background, .5];
title = highlights[[1]];
songs = highlights[[2]];
上面的公差值如下:.1
是&#34;分开&#34;之间的最小差异。颜色; .2
是众多主色之间的最小差异(较低的值可能会返回黑色和深灰色,而较高的值可确保主色的多样性); .5
是主色和背景之间的最小差异(较高的值会产生较高对比度的色彩组合)
瞧!
Graphics[{background, Disk[]}]
Graphics[{title, Disk[]}]
Graphics[{songs, Disk[]}]
该算法可以非常普遍地应用。我将上述设置和容差值调整到它们工作的程度,以便为我测试的约80%的专辑封面生成大致正确的颜色。当DominantColorsNew
没有找到要返回高亮的两种颜色时(即当专辑封面是单色时),会出现一些边缘情况。我的算法并没有解决这些问题,但复制iTunes&#39;功能:当相册产生少于两个高光时,标题会变为白色或黑色,具体取决于与背景的最佳对比度。然后歌曲成为一种高亮颜色(如果有的话),或者标题颜色逐渐淡入背景中。
答案 1 :(得分:44)
通过@ Seth-thompson的答案和@bluedog的评论,我构建了一个Objective-C(Cocoa-Touch)项目来生成图像功能的配色方案。
您可以在以下位置查看项目:
https://github.com/luisespinoza/LEColorPicker
目前,LEColorPicker正在做:
现在,我将检查ColorTunes项目(https://github.com/Dannvix/ColorTunes)和Wade Cosgrove项目的新功能。我也有一些改进配色方案结果的新想法。
答案 2 :(得分:16)
Panic的Wade Cosgrove写了一篇nice blog post来描述他的算法的实现,该算法与iTunes中的算法近似。它包括Objective-C中的示例实现。
答案 3 :(得分:15)
您也可以签出ColorTunes这是使用MMCQ(中值剪切颜色量化)算法的Itunes专辑视图的HTML实现。
答案 4 :(得分:5)
在@ Seth的回答中,我实现了算法,使用PHP和Imagick在图片的两个横向边框中获得主色。
https://gist.github.com/philix/5688064#file-simpleimage-php-L81
它用于填充http://festea.com.br
中封面照片的背景答案 5 :(得分:5)
我刚刚编写了一个JS库,它实现了与@Seth描述的算法大致相同的算法。它可以在github.com/arcanis/colibrijs免费获取,在NPM上可以colibrijs
免费获取。
答案 6 :(得分:4)
我在不同的背景下问了同样的问题,并向http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in-images/指出了学习算法(k均值),粗略地使用图像中的随机起点做同样的事情。这样,算法本身可以找到主色。