iTunes 11中为歌曲列表着色的算法如何工作?[关闭]


297

新的iTunes 11具有专辑歌曲列表的绝佳视图,可以选择专辑封面功能中的字体和背景颜色。有人知道算法是如何工作的吗?

第三个例子


9
w3c颜色对比度公式可能是答案的一部分。我自己的经验测试表明,MS Word使用此公式来确定其自动彩色字体。搜索“颜色亮度由以下公式确定” [w3c颜色对比度公式] [1] [1]:w3.org/TR/AERT#color-contrast
bluedog 2012年

@bluedog,我认为你是对的。我尝试了很多专辑封面,并且字体始终与背景有足够的对比度以清晰地观看。
LuisEspinoza

1
另外需要注意的是,Mac OS和Windows之间似乎有所不同:twitter.com/grimfrog/status/275187988374380546
Tom Irving

2
我可以想象,可能不仅是颜色的数量,还包括它们的饱和度值是计算的一部分:我的实验使我得出了这样的结论:突出显示的颜色经常被选作背景颜色,尽管它们出现在颜色的几个区域中。图片。这就是为什么我认为查看封面图像的直方图及其峰值可能会有用的原因,并且基于一些微调的参数来选择颜色。
拉斐尔2012年

Answers:


423

例子1

给定专辑封面作为输入,我估计了Mathematica中的iTunes 11颜色算法:

输出1

我是怎么做到的

经过反复试验,我想出了一种算法,该算法可用于大约80%的测试专辑。

颜色差异

该算法的大部分内容是寻找图像的主色。但是,找到主色的前提是计算两种颜色之间的可量化差异。一种计算两种颜色之间差异的方法是计算它们在RGB颜色空间中的欧式距离。但是,人类的色彩感知与RGB色彩空间中的距离并不能很好地匹配。

因此,我编写了一个将RGB颜色(以形式{1,1,1})转换为YUV的函数,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
    ]

其余算法

首先,我调整了专辑封面()的大小36px36px并使用双边滤镜缩小了细节

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]];

最后,我在整个图像中返回了2种主要颜色,并告诉该函数也滤除了背景颜色。

highlights = DominantColorsNew[Flatten[ImageData[thumb], 1], .1, 2, .2, 
    List @@ background, .5];
title = highlights[[1]];
songs = highlights[[2]];

上面的公差值如下:.1是“单独”颜色之间的最小差异;.2是许多主要颜色之间的最小差异(较低的值可能会返回黑色和深灰色,而较高的值则可以确保主要颜色的多样性);.5是主色和背景之间的最小差异(值越大,对比度越高的颜色组合)

瞧!

Graphics[{background, Disk[]}]
Graphics[{title, Disk[]}]
Graphics[{songs, Disk[]}]

最终输出

笔记

该算法可以非常普遍地应用。我调整了上述设置和公差值,使它们可以为我测试的专辑封面的〜80%产生大致正确的颜色。当DominantColorsNew找不到两种颜色返回高光时(例如,当专辑封面为单色时),会出现一些边缘情况。我的算法无法解决这些情况,但是复制iTunes的功能将是微不足道的:当专辑产生的突出显示少于两个时,标题将变为白色或黑色,具体取决于与背景的最佳对比度。然后,如果有一种,则歌曲变成一种突出显示的颜色,或者标题颜色逐渐淡入背景。

更多例子

更多例子


3
好吧,@ Seth Thompson,看起来非常有希望。我要自己尝试一下,这将需要几天时间,请耐心等待。
LuisEspinoza

6
很棒的解决方案。现在需要从Mathematica到Objective-C的移植,这是一场艰苦的斗争。
loretoparisi 2012年

1
+1非常详细的答案!
Marius Schulz

1
@cormullion LUV(和LAB)都旨在实现感知均匀性。但是,我没有找到任何在两个颜色空间中使用欧几里德距离的明确参考。我的猜测是,如果没有其他选择,它们都将比RGB更好。
塞斯·汤普森

6
这就是我所说的“查克·诺里斯答案”
MCKapur 2013年

44

通过@ Seth-thompson的回答和@bluedog的评论,我构建了一个小的Objective-C(可可触摸)项目,以生成具有图像功能的配色方案。

您可以在以下位置检查项目:

https://github.com/luisespinoza/LEColorPicker

现在,LEColorPicker正在做:

  1. 图像缩放到36x36像素(这减少了计算时间)。
  2. 它从图像生成像素阵列。
  3. 将像素数组转换为YUV空间。
  4. 像Seth Thompson的代码一样收集颜色。
  5. 颜色集按计数排​​序。
  6. 该算法选择三种最主要的颜色。
  7. 最主要的是作为背景。
  8. 使用w3c色彩对比公式测试第二和第三高的主要色彩,以检查色彩与背景的对比度是否足够。
  9. 如果其中一种文字颜色未通过测试,则根据Y分量将其指定为白色或黑色。

到目前为止,我将检查ColorTunes项目(https://github.com/Dannvix/ColorTunes)和Wade Cosgrove项目是否有新功能。另外,我还有一些新想法可以改善配色方案的结果。

Screenshot_Mona


2
+1-非常酷的东西,以及一个很好的例子,说明如何自己进行算法开发和应用程序开发都很有趣
Yuval Karmi 2013年

1
+1用于检查对比度。
brianmearns 2014年

是的很酷,但是您如何舍入每种颜色的哈希值?我认为我可以轻松地打破此算法,只需在右下角添加一个黑白的“ Explicit”徽标,您实际上就为黑白添加了焦点。无论如何,该算法对于基于剪贴画的图像会更好,但是如果您将图像设置为36x36,则抗锯齿​​处理将使那些失败的情况变得更加罕见
Jack Franzen 2014年

一句话:太神奇了!
Teddy


15

您可能还会签出ColorTunes,它是Itunes专辑视图的HTML实现,该视图使用MMCQ(中位数剪切颜色量化)算法。


是的,我已经检查过了。可悲的是似乎几乎没有记载。
LuisEspinoza

ColorTunes中的重要注释是对(中位数剪切量化算法)的引用[ leptonica.com/papers/mediancut.pdf]。我只是在大约2小时内就在python中实现了该功能,只是形成了本文中的描述,并且比我上面的Seth算法的实现更喜欢它。我更喜欢结果,但最重要的是速度要快得多(当然,我可能会错误地实现Seth算法)。
brianmearns 2014年

@ sh1ftst0rm您在github或其他地方有python实现吗?欢呼声
-Anentropic

@Anentropic对不起,我没有。这是我正在从事的一个私人项目的一部分,我根本没有将其提取出来。如果有机会,我会尝试将其发布在某个地方,但是可能不会很快发布。
brianmearns 2015年



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.