【问题标题】:Algorithm design: Image quantization for most prominent colors算法设计:最突出颜色的图像量化
【发布时间】:2014-12-17 13:30:03
【问题描述】:

所以我正在研究一种从图像中提取主色人类感知的方法。

例如,这是一张照片:https://500px.com/photo/63897015/looking-out-for-her-kittens-by-daniel-paulsson

大多数人会认为“主导”颜色是眼睛那刺眼的蔚蓝。但是,使用标准量化时,当您降至 16 种颜色以下时,蓝色会完全消失。眼睛只占画布的 0.2%,所以取平均值根本行不通。

项目详细信息:我正在构建一个 Rails 应用程序,它将接受上传的照片或特定颜色,并返回一堆具有相似主色的其他照片。设计师将使用该工具来查找与其预先存在的配色方案相匹配的库存照片。如果我能整理出技术方面的问题,我还有其他很酷的想法。

Current Research:在过去的 24 小时里,我一直在阅读有关这些内容的所有内容。在我尝试过的所有服务中,TinEye 是唯一一个做得很好的服务,但它们是闭源的。我不能提供超过 1 个链接,但你可以用谷歌搜索“TinEye Color”。

使用的工具:我正在使用 ImageMagick 进行图像转换和直方图生成。

期望的结果:当给定那张照片时,我想创建一个 5-6 种颜色的调色板,饱和的天蓝色就是其中之一。

当前方法:我现在的做法是将其减少到 32 或 64 种颜色,并寻找饱和度/色调异常值。如果标准差很低并且离群值很远,我会将其添加到调色板中。然后我会将照片进一步减少到 4 种颜色,并将它们组合成 5-6 种调色板。

我的问题:我的问题是 ImageMagick 的量化算法。我不想取颜色的平均值,我想将它们按相似的颜色分组并取中值,偏爱饱和颜色。当我将猫的图片减少到 32 种颜色时,眼睛会变成不饱和的灰色。

所以我问你们是否知道任何算法或颜色原理,可以让我找到从图像中脱颖而出的颜色,而不会使它们模糊在一起。我想要图像中实际存在的颜色,而不是 4-5 种颜色组合的模糊平均值。

从更一般的意义上说,TinEye 做得很完美,我想弄清楚他们是如何做到的。

【问题讨论】:

  • 你可以试试k-medoids集群。我的猜测是它会为某些初始化找到蓝色,但在其他初始化时不会。

标签: algorithm colors imagemagick image-manipulation quantization


【解决方案1】:

你说,'主导'颜色是'那刺眼的蔚蓝'

您还说,您希望 “饱和的天蓝色是”提取的调色板中的 5-6 种颜色之一。

您最终想要'图像中实际存在的颜色,而不是 4-5 种颜色组合的模糊平均值。'

为了开始处理这项任务,我首先尝试了解“那刺眼的蔚蓝”的确切颜色定义

但在这里我已经卡住了:那刺眼的天蓝色已经混合了至少 20 种不同深浅的蓝色!请看这里,一张剪裁后的猫眼图片,缩放比例为 1000%:

那么你到底想要哪一个?那么,如果你最终想象的蓝色的最佳匹配是 '模糊平均' 几种颜色的组合,而哪个不甚至出现在原始图像中一次?!


更新

这是我第一次尝试...

1。使用-posterize 8 减少颜色

convert 2048.jpg -posterize 8 posterized-8.png

这是猫眼在海报化和放大 1000% 时的样子:

2。创建一个文字“直方图”,描述分级后最常用的 12 种颜色

convert              \
   posterized-8.png  \
  -format %c         \
  -colorspace lab    \
  -colors 12         \
   histogram:info:-  | sort -n -r

  850708: (172,171,171) #ACABAB srgb(172,171,171)
  370610: (219,219,226) #DBDBE2 srgb(219,219,226)
  262870: (218,201,183) #DAC9B7 srgb(218,201,183)
  162588: (182,182,219) #B6B6DB srgb(182,182,219)
  161739: (182,219,219) #B6DBDB srgb(182,219,219)
  115671: ( 92, 87, 87) #5C5757 srgb(92,87,87)
  102337: (146,109,109) #926D6D srgb(146,109,109)
   86318: ( 67, 46, 46) #432E2E srgb(67,46,46)
   82882: ( 22, 20, 21) #161415 srgb(22,20,21)
   66221: (109,139,154) #6D8B9A srgb(109,139,154)
   58403: (146,146,109) #92926D srgb(146,146,109)
   38949: ( 97,109,146) #616D92 srgb(97,109,146)

3。使用 12 种最常见的颜色创建一个显示调色板的补丁条:

convert      \
   -size 100x100 \
    xc:"srgb(172,171,171)" \
    xc:"srgb(219,219,226)" \
    xc:"srgb(134,119,120)" \
    xc:"srgb(182,182,219)" \
    xc:"srgb(182,219,219)" \
    xc:"srgb(92,87,87)" \
    xc:"srgb(146,109,109)" \
    xc:"srgb(67,46,46)" \
    xc:"srgb(22,20,21)" \
    xc:"srgb(109,139,154)" \
    xc:"srgb(146,146,109)" \
    xc:"srgb(97,109,146)" \
   +append \
    palette.png

这是调色板的样子(它错过了眼睛中非常亮点的颜色):

【讨论】:

  • 嘿,Kurt,感谢您的回复 =) 是的,实际上我正在寻找一种方法将眼睛中的 20 种蓝色浓缩为单一的代表性颜色,但不仅仅是取平均值(因为平均值是暗灰色的蓝色)。我想在亮度和色调方面获取中值或模式样本,但在饱和度方面在 70-90% 的某个位置。我看看能不能解决,谢谢你的帮助!
  • 另外,您向我展示了 ImageMagick 的两个很棒的技巧:对直方图进行排序,以及将调色板作为图像输出。仅此一项就让我很开心=)
【解决方案2】:

这是一个初步的想法......我或其他人可能会进一步发展它。您的声明提示您希望使用饱和颜色。

首先,从照片中删除所有黑色和白色,因为它们是不饱和的。然后转换为 HSL 颜色空间并提取饱和度通道。对比度将饱和度拉伸到全范围,然后在应用 ImageMagick 的颜色量化算法时将其用作遮罩。

convert cat.png -fuzz 20% -fill black \
    -opaque white                     \
    -opaque black                     \
    -colorspace HSL -channel S -separate -contrast-stretch 0.1% out.png

【讨论】:

  • 太棒了!非常感谢您的回复,我肯定会玩这个。
猜你喜欢
  • 2011-07-06
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 2011-09-06
  • 1970-01-01
  • 2019-10-29
  • 2012-07-07
相关资源
最近更新 更多