跟进:通过独特性对颜色进行“排序”

原始问题

如果你给了N个最远距离的颜色(以及一些相关的距离度量),你能想出一种方法将这些颜色排序成某种顺序,这样第一个M也相当接近于最大不同的集合?

换句话说,给定一组不同的颜色,提出一个排序,这样我就可以使用尽可能多的颜色,从一开始就可以开始使用,并且可以合理地确信它们都是独特的,并且附近的颜色也非常独特(例如,蓝红不在红蓝旁边)。

随机化是好的,但肯定不是最佳的。

澄清:给一些大和视觉上不同的颜色集(比如256或1024),我想对它们进行排序,这样当我使用他们的第一个,比如说16,我得到的颜色相对视觉上不同的子集。这相当于,粗略来算,说我要排序的1024这个列表中,以便更接近个人的颜色在视觉上,相隔越远,他们都在名单上。

0
额外 编辑
意见: 1

9 答案

您可以将它们分成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

所以你需要决定的唯一的事情是你想要的颜色有多近,以及这些细分被认为是不同的可接受的差异。

0
额外

看起来知觉对你很重要,在这种情况下,你可能需要考虑使用YUV,YCbCr或Lab等感知色彩空间。每次我使用它们,它们都给了我比单独使用sRGB更好的结果。

转换成sRGB和从sRGB转换可能会很痛苦,但在你的情况下,它实际上可以使算法更简单,作为奖励,它也将主要用于色盲!

0
额外

Do you mean that from a set of N colors, you need to pick M colors, where M < N, such that M is the best representation of the N colors in the M space?

作为一个更好的例子,将真彩色(24位色彩空间)降低到8位映射色彩空间(GIF?)。

这里有量化算法,就像ImageMagic使用的自适应空间细分算法。

这些算法通常不会从源空间中选取现有颜色,而是在目标空间中创建与源颜色非常相似的新颜色。作为一个简单的例子,如果您在原始图像中有三种颜色,其中两种颜色是红色的(具有不同的强度或蓝色色调等),第三种颜色是蓝色,并且需要减少到两种颜色,则目标图像可以具有红色这是原始图像中原始的两种红色+蓝色的某种平均值。

如果你需要别的东西,那么我不明白你的问题:)

0
额外

这对我来说听起来像是某种阻力图,您试图找出阻力最小的路径。如果你反过来要求,最大阻力的路径,它也许可以用来产生一组从一开始就产生最大差异的结果,并且在结束时开始返回到更接近于其他的值。

例如,这里有一种方法可能做你想做的事。

  1. Calculate the distance (ref your other post) from each color to all other colors
  2. Sum the distances for each color, this gives you an indication for how far away this color is from all other colors in total
  3. Order the list by distance, going down

这似乎会产生一个列表,以距离所有其他颜色最远的颜色开始,然后向下,列表末尾的颜色将更接近其他颜色。

编辑:阅读你对我的第一篇文章的回复,关于空间细分,不会完全符合上面的描述,因为接近其他颜色的颜色会落到列表的底部,但假设你有一个颜色簇,在某处来自该群集的至少一种颜色将位于列表的开始附近,并且将总体上离所有其他颜色最远。如果这是有道理的。

0
额外

您可以根据最小距离的最大距离将候选颜色排序到任何索引颜色。

使用欧几里德颜色距离:

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;
            }
        }
    }
}
0
额外
尽管如此,这可能会从候选颜色中选择两种非常相似的颜色。您可能只想找到最佳的候选颜色,将其添加到索引颜色,然后重新开始。
额外 作者 Tatarize,

如果我正确地理解了这个问题,您希望获得具有最高平均距离M 颜色的子集,给定一些距离函数 d EM>。

换一种说法,将最初的 N 颜色设置为所有颜色连接的大型无向图,您需要找到最长路径,以访问任何 M 节点。

解决NP-complete图形问题远远超出了我的想法,但您可以尝试运行一个简单的物理模拟:

  1. Generate M random points in colour space
  2. Calculate the distance between each point
  3. Calculate repulsion vectors for each point that will move it away from all other points (using 1 / (distance ^ 2) as the magnitude of the vector)
  4. Sum the repulsion vectors for each point
  5. Update the position of each point according to the summed repulsion vectors
  6. Constrain any out of bound coordinates (such as luminosity going negative or above one)
  7. Repeat from step 2 until the points stabilise
  8. For each point, select the nearest colour from the original set of N

它远没有效率,但对于小型的M&lt; em&gt;它可能是有效的,并且它会得到接近最佳的结果。

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

0
额外
这不是NP完整的。它是按任何索引颜色O(N)的最小距离或由平均O(N)排序O(NLog(N))。显然是O(N + NLog(N))或O(NLog(N))。最坏的情况下,您需要将已排序的颜色添加到索引颜色,使其成为N²Log(N)。找到最好的,将它添加到索引颜色列表中。重来。
额外 作者 Tatarize,

这个问题被称为颜色量化,并且有许多众所周知的算法: http://en.wikipedia.org/ wiki / Color_quantization 我认识那些实施八叉树方法以达到良好效果的人。

0
额外

N个最远距离的颜色可以被认为是三维(彩色)空间中的一组分布良好的点。如果您可以从 Halton序列生成它们,则任何前缀(前M种颜色)也会由分布良好的点组成。

0
额外
  1. 从两个列表开始。 CandidateColors,最初包含您独特的颜色和SortedColors,最初为空。
  2. 选择任何颜色并将其从CandidateColors中移除并放入SortedColors中。这是第一种颜色,将是最常见的颜色,所以它是一个很好的选择颜色的应用程序。
  3. CandidateColors中的每种颜色都会计算其总距离。总距离是从CandidateColor到SortedColors中每种颜色的距离的总和。
  4. 从CandidateColors中移除距离最大的颜色并将其添加到SortedColors的结尾。
  5. 如果CandidateColors不为空,请返回步骤3。

这贪婪的算法应该给你很好的结果。

0
额外