这是什么颜色的?第二部分

2020-10-14 07:57:17

正如我们在上一篇关于颜色的帖子中所描述的那样,我们必须从衣服的图像中找到它们的颜色。这将在许多方面对我们有所帮助,包括决定购买哪些款式,以及将它们送到哪些客户手中。我们描述了人机混合的方法,但只深入到人的部分:将我们的图像转换成颜色的层次。在这篇文章中,我们将深入讨论计算部分:我们当前的计算机视觉算法,我们提出该算法的一些过程,以及我们下一步要做什么的想法。

在开发算法之前,我们必须考虑如何对其进行评估。如果我们做一个算法,它说“这个图像是这些颜色”,对吗?“正确”是什么意思?

对于这项任务,我们决定了两个重要的维度:正确的主色标签和正确的颜色数量。我们将其作为我们的算法预测的主色与地面真实主色之间的CIEDE 2000距离(如在SCRICIT-IMAGE中实现)以及颜色数量的平均绝对误差来操作。我们决定这样做有几个原因:

如果我们有更多的指标,可能很难选择一个“最佳”算法。

反正很多衣服只有一到两种颜色,我们的很多工序都依赖于主色。因此,校正主色比校正第二或第三种颜色重要得多。

那地面实况数据呢?我们有我们的销售团队提供的标签,但是我们的工具只允许他们选择像“灰色”或“蓝色”这样的宽泛的颜色,而不是一个确切的值。这些宽泛的颜色包含了很多东西,所以我们不能用它们作为基本事实。我们必须建立我们自己的数据集。

您的一些想法可能会跳到机械土耳其或其他标签服务。但是我们不需要太多的图片,所以描述这项任务可能比仅仅做这件事更难。此外,构建数据集有助于我们更好地理解数据。使用快速而肮脏的HTML/Javascript,我们随机选择了1000个图像,挑选出代表每个图像的主色的像素,并标记我们看到的不同颜色的数量。现在很容易得到两个数字(主色的平均CIEDE距离和颜色数量的MAE),它们告诉我们算法做得有多好。

有时,我们还通过在同一图像上运行两个算法并用两个颜色列表显示项目来进行一些手动验证。然后,我们手动对其中约200种颜色进行评分,选择哪种颜色更“好”。这种与数据的接触很重要,不仅是为了得到一个结果(“算法B在70%的时间里比A好”),而且是为了了解每个簇中发生了什么(“算法B往往选择太多的集群,但是算法A错过了一些非常浅的颜色”)。

在处理图像之前,我们将其转换为CIELAB(或LAB)颜色空间,而不是更常见的RGB颜色空间。Lab点(严格地说是L*a*b*,不过为简单起见,我们在本文中将其称为Lab)代表三个不同的轴,而不是代表图像中红色、绿色和蓝色的数量。L表示亮度,从黑色(0)到白色(100)。A和B在两个部分中表示颜色:A的范围从绿色(-128)到红色(127),B的范围从蓝色(-128)到黄色(127)。这种颜色空间的主要好处是其近似的感知一致性:两个实验室点之间具有相同的欧几里得距离,无论它们位于空间的哪个位置,它们看起来都大致相同。

当然,LAB还引入了其他困难:值得注意的是,图像总是在使用设备相关RGB色彩空间的计算机屏幕上查看。此外,Lab色域比RGB色域宽,这意味着Lab可以表达RGB不能表达的颜色。这意味着LAB-RGB转换不是双向的;如果您将点从LAB转换为RGB,然后再转换回来,您可能不会获得完全相同的点。我们承认在这项工作的其余部分,这些都是理论上的缺陷,但在经验上是可行的。

在我们转换为LAB之后,我们有一系列的像素,可以看到它们是(L,A,B,X,Y)点。我们算法的其余部分是对这些点的两阶段聚类,其中第一阶段基于所有5个维度进行聚类,第二阶段省略X和Y维度。

我们从一张扁平物品的图像开始,它已经按照上一篇文章中的描述进行了颜色校正,缩小到300x200,并转换为Lab。

这已经使我们的图像从60,000像素增加到几百个超像素,消除了很多不必要的复杂性。我们甚至可以通过合并接近相同颜色的相邻超像素来进一步减少这些超像素。为此,我们在这些超像素上绘制一个区域邻接图:如果两个超像素的像素接触,则该图中的两个超像素是相连的。

左:此羊毛衫上的区域邻接图(RAG)。两个超像素之间的暗线表明,这两个超像素的颜色没有太大差异,因此它们可以合并。明亮的线条(或没有线条)表示这些颜色之间的差异很大,因此它们不应该合并。右图:在碎布上设置阈值后合并的超像素。

这个图的节点是我们之前计算的超像素,边是超像素之间在颜色空间上的差异。颜色非常相似的两个附近的超像素将具有较低的权重(对应于图像中的暗线),而颜色非常不同的超像素将具有较高的权重(明亮的颜色,或者如果边缘权重大于20,则甚至不会在此图像中绘制)。有很多方法可以计算出如何组合附近的超像素,但我们发现10的简单阈值效果很好。

现在,在这种情况下,60,000个像素已经减少到大约100个区域,其中一个区域内的每个像素都具有相同的颜色。这有一些很好的计算好处:首先,我们知道背景是那个几乎是纯白的大超像素,我们可以很容易地删除它。(我们删除L>;99以及A和B都在-0.5到0.5之间的任何超像素。)。其次,我们可以在下一步大幅减少要聚类的像素。我们不能将它们减少到只有100个,因为我们想要根据区域中的像素数对它们进行加权。但是,我们可以安全地从每个聚类中删除90%的像素,而不会丢失太多细节,也不会过多地影响下一聚类步骤。

在这一点上,我们有几千个(L,A,B)像素。有很多方法可以整齐地对这些像素进行聚类;我们选择K-Means是因为它运行速度快,易于理解,我们的数据只有3维,而且实验室空间中的欧几里德距离是有意义的。

我们在这里并不是很聪明:我们只是简单地使用K=8进行聚类。如果任何聚类包含的点少于3%,我们就会在K=7,然后6,以此类推的情况下再次尝试使用K=7,然后再尝试6,依此类推。这为我们提供了一个包含1到8个群集中心的列表,以及每个中心包含多少个点的分数。我们使用Colornamer为它们添加名称,正如我们在上一篇文章中所描述的那样。

我们已经实现了CIEDE 2000的预测颜色和地面真实颜色之间的平均距离为5.86。要很好地解释这个数字是很棘手的。按照一个更简单的距离度量CIE76,我们的平均距离是7.82;在这个度量上,2.3相当于一个非常明显的差异。所以我们可以说,我们的结果相差3个多一点,仅仅是明显的差别。

我们在颜色数量上也有2.28的MAE。再说一次,这是一个非常次要的指标。下面描述的许多其他算法(特别是间隙统计)减少了该误差,但代价是增加了第一颜色距离。忽略虚假的第5和第6色要比忽略错误的第1色容易得多。

即使是明显只有一种颜色的物品,比如这些短裤,也会因为阴影而包含看起来更暗的区域。

阴影仍然是一个问题。因为布料从来不会完全平放,所以图像的某些部分总是留在阴影中,因此看起来像是一种单独的颜色。像删除具有相似色调和不同亮度的颜色这样的简单方法不起作用,因为从“无阴影像素”到“阴影像素”的转换并不总是一致的。在未来,我们希望使用一些更聪明的技术,如DeshadowNet或自动阴影检测来消除它们。

到目前为止,我们只关注服装图像。首饰和鞋子会带来问题:我们的首饰照片非常小,我们的鞋子照片通常包含鞋子的内部。在上面的例子中,我们会将这双鞋标记为勃艮第和西耶娜,尽管只有勃艮第是重要的。

虽然我们的最终算法看起来很简单,但要想出它并不简单!在本节中,我们将详细介绍我们在此过程中尝试和学习的一些变体。

我们已经尝试过去除背景的算法,比如这个来自Lyst的算法。非正式评估显示,它们不像去除白色背景那样精确。然而,我们计划更深入地挖掘这一点,因为我们正在对我们的照相馆没有处理的图像进行更多的处理!

有几个颜色选择库已经实现了一个非常简单的解决方案来解决这个问题:通过将像素散列到几个宽桶中对其进行聚类,然后返回具有最多像素的桶的平均LAB值。我们尝试了一个名为Colorgram.py的库;尽管它很简单,但它工作得出奇地好。它的工作速度也很快:每张图像不到1秒,而我们的算法是几十秒。然而,Colorgram到主色的平均距离比我们现有的算法要大,这主要是因为它的结果是大桶的平均。然而,我们仍然在速度比准确性更重要的情况下使用它。

我们使用QuickShift算法将图像分割成超像素,但有许多可能的算法,如SLIC、分水岭和Felzenszwalb。从经验来看,我们使用QuickShift的效果最好,因为它的结果细节很好。例如,SLiC似乎在条纹等功能上遇到了麻烦,这些功能以一种不太紧凑的方式占用了大量空间。以下是具有各种参数值的SLIC的一些有代表性的结果:

QuickShift对我们的数据有一个理论上的优势:它不要求它的超像素是完全连接的。研究人员已经注意到,这可能会带来问题,但在我们的情况下,这是一个好处,因为我们通常有一些小而详细的区域,我们希望所有这些区域都成为同一个集群。

(虽然超像素群集看起来一团糟,但它实际上是将这件衬衫中的所有红线与其他红线分组,将蓝线与蓝线分组,等等。)。

当使用K-Means时,一个常见的问题是“K应该是什么?”也就是说,如果我们想将我们的点聚集到一定数量的簇中,我们应该有多少簇呢?已经开发了许多解决方案。最简单的是肘部方法,但这需要手动查看图表,我们需要一个全自动的解决方案。Gap统计使该方法形式化,并且使用它我们在“颜色的数量”度量上获得了更好的结果,但代价是在主色上的一些精确度。因为主色比较重要,我们还没有投入生产,但我们计划进行更多的调查。最后,轮廓方法是另一种流行的选择K的方法,它产生的结果也比我们现有的算法略差,并且有一个主要的缺点:它至少需要2个聚类。很多衣服只有一种颜色。

“K应该是什么?”这个问题的一个潜在解决方案。是使用一种不需要指定K的算法。一个流行的例子是DBSCAN,它在数据中查找密度相似的集群。

左图:一件五颜六色的上衣。右:左侧图像中的每个像素,在实验室空间中打印。请注意,不幸的是,像素没有形成清晰的青色和紫色簇。

通常我们没有这些星团,或者因为人类的感知,我们有看起来像星团的东西。在我们看来,左边衣服上的青色布塔元素从紫色背景中突出出来,但当我们在RGB或Lab空间中绘制每个像素时,它们并没有形成簇。尽管如此,我们还是尝试了DBSCAN,使用不同的epsilon值,但得到的结果不出所料地平淡无奇。

一个很好的研究原则是看看是否有人已经解决了你的问题。事实上,Algolia的Léo Ercolanelli早在三年前就在他们的博客上发布了一个深入的解决方案。由于他们慷慨的开源,我们能够尝试他们的确切解决方案。然而,根据地面真实数据集,我们得到的结果略差,因此我们坚持使用现有算法。他们正在解决一个与我们现在不同的问题:非白色背景的模型上的商品图片,所以我们的结果会略有不同是有道理的。

这个算法完成了我们在上一篇文章中描述的过程。在我们提取这些聚类中心之后,我们使用Colornamer来应用名称,然后将这些颜色导入到我们的内部工具和算法中。这目前帮助我们很容易地按颜色可视化我们的商品;我们希望也能将其包括在我们的购买和造型推荐系统中。虽然这个过程不是一个完美的解决方案,但它帮助我们获得了更好的关于我们数千件商品的数据,这反过来又提高了我们的最终目标:帮助人们找到他们喜欢的款式。

我们是一个多元化的团队,致力于制造伟大的产品,我们希望您的帮助。你想与令人惊叹的同行一起打造令人惊叹的产品吗?加入我们!