为 iTunes 11 中的歌曲列表着色的算法如何工作? [关闭]
Posted
技术标签:
【中文标题】为 iTunes 11 中的歌曲列表着色的算法如何工作? [关闭]【英文标题】:How does the algorithm to color the song list in iTunes 11 work? [closed] 【发布时间】:2012-11-18 05:47:37 【问题描述】:新的 iTunes 11 有一个非常好的专辑歌曲列表视图,在专辑封面功能中为字体和背景选择颜色。有人知道算法是如何工作的吗?
【问题讨论】:
w3c 颜色对比度公式可能是答案的一部分。我自己的经验测试表明 MS Word 使用这个公式来确定它的自动颜色字体。搜索“颜色亮度由以下公式确定”[w3c颜色对比度公式][1][1]:w3.org/TR/AERT#color-contrast @bluedog ,我认为你是对的。我尝试了很多专辑封面,字体与背景的对比度始终足够清晰。 另外需要注意的是,Mac OS 和 Windows 之间似乎有所不同:twitter.com/grimfrog/status/275187988374380546 我可以想象,不仅颜色的数量,而且它们的饱和度值也是计算的一部分:我的实验使我得出结论,高亮颜色通常被选为背景颜色尽管它们出现在图像的少数区域。这就是为什么我认为查看封面图像的直方图及其峰值可能很有用,并且基于一些微调参数,选择颜色。 在panic.com/blog/2012/12/itunes-11-and-colors查看另一个答案 【参考方案1】:给定专辑封面作为输入,我在 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
)并使用双边过滤器减少了细节
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
是“分离”颜色之间的最小差异; .2
是众多主色之间的最小差异(较低的值可能会返回黑色和深灰色,而较高的值可确保主色的多样性); .5
是主色和背景之间的最小差异(较高的值将产生较高对比度的颜色组合)
瞧!
Graphics[background, Disk[]]
Graphics[title, Disk[]]
Graphics[songs, Disk[]]
注意事项
该算法可以非常普遍地应用。我调整了上述设置和容差值,使其能够为我测试的大约 80% 的专辑封面生成通常正确的颜色。当DominantColorsNew
没有找到两种颜色来返回高亮时(即专辑封面是单色时),会出现一些边缘情况。我的算法没有解决这些情况,但复制 iTunes 的功能将是微不足道的:当专辑产生少于两个亮点时,标题会根据与背景的最佳对比度变为白色或黑色。然后歌曲成为一种突出显示颜色(如果有的话),或者标题颜色稍微淡入背景。
更多示例
【讨论】:
好的@Seth Thompson,看起来很有希望。我自己试试,这需要几天时间,请耐心等待。 非常棒的解决方案。现在需要一个从 Mathematica 到 Objective-C 的端口,这是一场艰苦的斗争。 这个非常详细的答案+1! @cormullion LUV(和 LAB)都以感知一致性为目标。但是,我没有找到在任何一种颜色空间中使用欧几里得距离的任何明确参考。我的猜测是,如果不出意外,它们都会比 RGB 更好。 这就是我喜欢称之为“查克诺里斯的答案”【参考方案2】:根据@Seth-thompson 的回答和@bluedog 的评论,我构建了一个小的Objective-C (Cocoa-Touch) 项目来生成图像功能的配色方案。
您可以在以下位置查看项目:
https://github.com/luisespinoza/LEColorPicker
目前,LEColorPicker 正在做:
-
图像缩放为 36x36 像素(这减少了计算时间)。
它从图像生成像素阵列。
将像素数组转换为 YUV 空间。
按照 Seth Thompson 的代码收集颜色。
颜色集按计数排序。
算法选择三种最主要的颜色。
最主要的被指定为背景。
使用 w3c 颜色对比度公式测试第二个和第三个主要颜色,以检查颜色是否与背景有足够的对比度。
如果其中一种文本颜色未通过测试,则根据 Y 分量分配为白色或黑色。
就目前而言,我将检查 ColorTunes 项目 (https://github.com/Dannvix/ColorTunes) 和 Wade Cosgrove 项目的新功能。我也有一些改进配色方案结果的新想法。
【讨论】:
+1 - 非常酷的东西,是算法开发和应用程序开发本身就非常有趣的一个很好的例子 +1 用于检查对比度。 是的,很酷,但是你如何四舍五入每种颜色的哈希值?我想我可以很容易地打破这个算法,只需在右下角添加一个小小的黑白“显式”标志,你真的是在为黑白添加焦点。无论如何,这种算法对于基于剪贴画的图像会更好,但是如果你有 36x36 的图像,那么抗锯齿会使这些失败情况变得更加罕见 一个字:太棒了!【参考方案3】:Panic 的 Wade Cosgrove 写了一封 nice blog post,描述了他实现的一种算法,该算法与 iTunes 中的算法相近。它包含一个 Objective-C 中的示例实现。
【讨论】:
【参考方案4】:您还可以查看ColorTunes,它是使用 MMCQ(中值剪切颜色量化)算法的 Itunes 专辑视图的 html 实现。
【讨论】:
是的,我已经检查过了。可悲的是似乎几乎没有记录。 ColorTunes 中的重要注释是对(中值切割量化算法)[leptonica.com/papers/mediancut.pdf].我只是在大约 2 小时内用 python 实现了这个,只是形成了论文中的描述,并且更喜欢它而不是我上面的 Seth 算法的实现。我更喜欢结果,但最重要的是它更快(当然,我可能错误地实现了 Seth 的算法)。 @sh1ftst0rm 你在 github 或其他地方有你的 python 实现吗?欢呼 @Anentropic 对不起,我没有。这是我正在从事的一个私人项目的一部分,我根本没有把它提取出来。如果有机会,我会尝试将其发布到某个地方,但可能不会很快发布。【参考方案5】:我刚刚编写了一个 JS 库,实现了与 @Seth 描述的算法大致相同的算法。它在github.com/arcanis/colibrijs 上免费提供,在 NPM 上作为colibrijs
提供。
【讨论】:
【参考方案6】:根据@Seth 的回答,我使用 php 和 Imagick 实现了算法以在图片的两个横向边框中获取主色。
https://gist.github.com/philix/5688064#file-simpleimage-php-L81
用于填充http://festea.com.br的封面照片背景
【讨论】:
【参考方案7】:我在不同的上下文中问了同样的问题,并被指向http://charlesleifer.com/blog/using-python-and-k-means-to-find-the-dominant-colors-in-images/ 的学习算法(k 均值),该算法使用图像中的随机起点粗略地做同样的事情。这样,算法就可以自行找到主色。
【讨论】:
以上是关于为 iTunes 11 中的歌曲列表着色的算法如何工作? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何删除iTunes / Music Library中的重复歌曲?
如何在最近 5 天内按播放次数获得 iTunes 库前 10 首歌曲?
从电脑上下载歌曲至iphone手机上,如何把此歌曲设置为铃声?