algorithm -按显著性对颜色进行排序

Translate

原始问题

如果为您提供了N个最大距离的颜色(以及一些相关的距离度量),您是否可以提出一种将这些颜色按某种顺序排序的方法,以使第一个M也可以合理地接近最大不同的颜色集?

换句话说,给定一堆不同的颜色,提出一个顺序,这样我就可以从开始就使用任意数量的颜色,并可以合理地确保它们都是不同的,并且附近的颜色也非常不同(例如,蓝红色不紧靠红蓝色)。

随机化是可以的,但肯定不是最优的。

澄清:给定一些大的,视觉上不同的颜色(例如256或1024),我想对它们进行排序,这样当我使用第一个(例如16种)时,我会得到一个在视觉上相对不同的颜色子集。大致上,这相当于说我要对1024个列表进行排序,以便视觉上各个颜色的距离越近,它们在列表中的距离就越远。

This question and all comments follow the "Attribution Required."

所有的回答

Translate

在我看来,这听起来像是电阻图在这里您尝试绘制阻力最小的路径。如果您颠倒了要求,即最大阻力的路径,则可能会使用它来生成一组,从一开始就产生最大的差值,直到结束时才开始返回更接近其他值的值。

例如,这是一种也许可以做您想要的事情的方法。

  1. 计算距离(参考你的其他帖子)(从每种颜色到所有其他颜色)
  2. 总结每种颜色的距离,这可以为您指示该颜色与所有其他颜色的总距离
  3. 按距离排序列表,向下排序

看起来,这将产生一个列表,该列表以与所有其他颜色相距最远的颜色开始,然后下降,直至列表末尾的颜色通常更接近于其他颜色。

编辑:阅读您对我关于空间细分的第一篇文章的回复并不完全符合上面的描述,因为接近其他颜色的颜色将落在列表的底部,但是假设您在某处有一个颜色簇该簇中的至少一种颜色将位于列表的开头附近,并且通常是与所有其他颜色相距最远的颜色。如果这样的话。

来源
Translate

这个问题称为色彩量化,并且有许多众所周知的算法:http://en.wikipedia.org/wiki/Color_quantization我知道实施八叉树方法取得良好效果的人。

来源
Translate

感觉对您来说很重要,在这种情况下,您可能需要考虑使用诸如YUV,YCbCr或Lab之类的可感知色彩空间。每次使用它们时,它们给我的效果都比单独使用sRGB好得多。

往返于sRGB可能会很痛苦,但是在您的情况下,它实际上可以使算法更简单,此外,它也同样适用于色盲!

来源
Translate

可以将N个最大距离的颜色视为3维(彩色)空间中一组分布良好的点。如果可以从霍尔顿序列,则任何前缀(前M个颜色)也由分布良好的点组成。

来源
Translate

如果我对问题的理解正确,则希望获得M颜色与最高平均距离颜色之间,具有一定的距离函数d.

换句话说,考虑初始设置N颜色作为连接所有颜色的大型无向图,您需要找到最长的路径拜访任何M节点。

恐怕我无法解决NP完全图的问题,但是您可以尝试运行简单的物理模拟:

  1. 生成M颜色空间中的随机点
  2. 计算每个点之间的距离
  3. 计算每个点的排斥向量,以使其远离所有其他点(使用1 /(距离^ 2)作为向量的大小)
  4. 对每个点的排斥向量求和
  5. 根据相加的排斥向量更新每个点的位置
  6. 约束任何超出范围的坐标(例如,亮度变为负值或大于一个)
  7. 从步骤2重复直到各点稳定
  8. 对于每个点,请从原始设置中选择最接近的颜色N

它远非高效,但规模很小M它可能足够有效,并且将提供接近最佳的结果。

如果您的色距函数很简单,则可能会有更多确定性的方式来生成最佳子集。

来源
Translate
  1. 从两个列表开始。 CandidateColors(最初包含您的不同颜色)和SortedColors(最初为空)。
  2. 选择任何颜色并将其从CandidateColors中删除,然后将其放入SortedColors中。这是第一种颜色,并且将是最常见的颜色,因此是选择与您的应用程序搭配得很好的颜色的好地方。
  3. 对于CandidateColors中的每种颜色,计算其总距离。总距离是从CandidateColor到SortedColors中每种颜色的距离之和。
  4. 删除与CandidateColors的总距离最大的颜色,并将其添加到SortedColors的末尾。
  5. 如果CandidateColors不为空,请返回步骤3。

这种贪婪算法应该会给您带来良好的效果。

来源
Translate

您可以根据与任何索引颜色之间的最小距离的最大距离对候选颜色进行排序。

使用欧几里得颜色距离:

public double colordistance(Color color0, Color color1) {
    int c0 = color0.getRGB();
    int c1 = color1.getRGB();
    return distance(((c0>>16)&0xFF), ((c0>>8)&0xFF), (c0&0xFF), ((c1>>16)&0xFF), ((c1>>8)&0xFF), (c1&0xFF));
}

public double distance(int r1, int g1, int b1, int r2, int g2, int b2) {
    int dr = (r1 - r2);
    int dg = (g1 - g2);
    int db = (b1 - b2);
    return Math.sqrt(dr * dr + dg * dg + db * db);
}

虽然您可以用任何想要的东西代替它。它只需要一个色距例程即可。

public void colordistancesort(Color[] candidateColors, Color[] indexColors) {
    double current;

    double distance[] = new double[candidateColors.length];
    for (int j = 0; j < candidateColors.length; j++) {
        distance[j] = -1;
        for (int k = 0; k < indexColors.length; k++) {
            current = colordistance(indexColors[k], candidateColors[j]);
            if ((distance[j] == -1) || (current < distance[j])) {
                distance[j] = current;
            }
        }
    }

    //just sorts.
    for (int j = 0; j < candidateColors.length; j++) {
        for (int k = j + 1; k < candidateColors.length; k++) {
            if (distance[j] > distance[k]) {
                double d = distance[k];
                distance[k] = distance[j];
                distance[j] = d;

                Color m = candidateColors[k];
                candidateColors[k] = candidateColors[j];
                candidateColors[j] = m;
            }
        }
    }
}
来源
Translate

您是说要从一组N种颜色中选择M种颜色,其中M <N,以便M是最好M空间中N种颜色的表示形式?

作为更好的例子,将真彩色(24位色彩空间)减少为8位映射色彩空间(GIF?)。

有一些对此的量化算法,例如自适应空间细分ImageMagic使用的算法。

这些算法通常不仅从源空间中选择现有颜色,而且还会在目标空间中创建与源颜色最相似的新颜色。举一个简化的例子,如果原始图像中有3种颜色,其中两种是红色(强度或蓝调等),而第三种是蓝色,并且需要减少为两种颜色,则目标图像可能会是红色这是原始图像中原始两个红色+蓝色的平均值。

如果您需要其他东西,那么我不明白您的问题:)

来源
Translate

您可以将它们拆分为RGB HEX格式,以便可以将R与不同颜色的R(与G和B相同)进行比较。

与HTML格式相同

XX XX XX
RR GG BB

00 00 00 = black
ff ff ff = white
ff 00 00 = red
00 ff 00 = green
00 00 ff = blue

因此,您唯一需要决定的就是颜色要多近,以及将这些段视为不同的可接受差异。

来源