有没有办法分割RGB颜色调色板?

5
我正在尝试生成一个包含16种颜色的调色板,将在4x4网格中显示。
因此,我必须找到一种方法来划分具有255*255*255种颜色的rgb颜色调色板,使其平均且逻辑合理地分成16种颜色。
我认为这将是一个数学算法,因为我正在尝试从3x3矩阵中选择16个向量,这些向量被等比例地选取。

你正在尝试从一个三维空间中挑选16个向量,每个维度有255个元素。这不是一个3x3矩阵。由于3不能被16整除(如果可以的话,这将是微不足道的),这也很难均匀地完成。也许从色彩理论中能找到一些解决方法。就目前而言,这让我想起了球装填问题。 - aaronasterling
或者说,这是球体堆积问题的一个变种(实际上是相反的),因为你想要将16个球尽可能远地放置在三维空间中。 - aaronasterling
是的,你说得对,实际上我不太擅长这个,我以为有一些方法/已知的解决方案可以解决这个问题。你听说过这种事吗? - Mehmet Fatih Yıldız
好像这不是一个简单的问题,但是不需要过多地思考,为什么不创建一个由16个色调和饱和度线性向量组成的矩阵呢?我的意思是 1 x 16,并将它们显示为方格图。 - jsan
7个回答

7
实际上,我已经找到了一种解决“分割调色板”问题的方法。我将使用这些颜色值,并将RGB值转换为HSV值。
色相、饱和度、亮度
因此,我可以使用0-360之间的一个整数值,或者我可以使用0-100(%)之间的一个整数值来表示我的调色板。
最后,我可以根据颜色选择轻松地使用这些值来搜索/过滤我的数据。我将0-360范围分成16个等份,因此我可以轻松地定义16种不同的颜色。
但还是感谢不同的方法。

但是,正如supercat建议的那样,您可能希望将色调和值差异结合起来,因为单独使用它们会产生在24位颜色中难以区分的项目。 - msw

3
你基本上是将一个立方体(R X G X B)投影到一个正方形(4 X 4)上。首先,我会问自己什么大小的立方体适合放在这个正方形里。
1 X 1 X 1 =  1
2 X 2 X 2 =  8
3 X 3 X 3 = 27

在正方形中能够放入的最大的立方体有8种颜色。此时,我会注意到8是16的一个整除因子,这很方便。
我认为这个方便会诱使我使用8种基本颜色,分别用浅色和深色或饱和度高和低的两种变体。

没关系。均匀分配8个元素和16个元素一样难。 - aaronasterling

3
你可以把它作为一个纯数学均分问题来解决,但实际上它并不涉及颜色。如果你试图按一种对人类感知有意义的方式均分颜色调色板,就需要考虑大量非线性因素,this article只是提到了其中一些。例如,颜色#fffffe#fffeff#feffff占据数学空间的远端,但对于人眼来说几乎无法区分。

你所给的三种颜色都聚集在原点附近;虽然这只是个例子。 - aaronasterling
1
你只是把坐标轴的编号搞反了 ;) 不过我明白你的意思。 - msw

3
当所选颜色数量很少(尤其是与可用颜色数量相比时),你最好手动选择好看的调色板或使用标准的调色板(比如预定义的16色系统或Web调色板),而不是试图发明一个数学算法来选择调色板。

1
+1 我认为这是最好的解决方案。我已经尝试了等分的方法,但它很难看。最好手动挑选它们。 - aaronasterling
是的,我更喜欢这样做,但实际上我要将这个调色板集成到搜索逻辑中,所以我会选择一种数学方法。 - Mehmet Fatih Yıldız

2
很多东西都取决于颜色的用途。如果你只想要16种任意的颜色,我建议使用以下颜色:
黑色    暗灰色   浅灰色  白色
深红色  深绿色  深蓝色  暗黄色
中红色  中绿色  中蓝色  中黄色
浅红色  浅绿色  浅蓝色  浅黄色
我在一个有点卡通色彩的游戏(VGA)中使用了这个颜色集,并发现它效果相当不错。我认为我将颜色序列排列得有点不同,但以上序列如果按4x4的方格排列似乎更合理。

2
这是一个标准问题,被称为颜色量化。有几种算法可供选择:
目标:您基本上想在三维空间中创建16个像素簇,其中3个轴的变化范围从0到255。
方法有: 1)四舍五入第一有效位。--非常容易实现,但效果不好。 2)直方图法。-需要中等努力并且能够给出更好的结果 3)四叉树。-最先进的数据结构。提供最佳结果,但实现四叉树数据结构很难。
可能还有其他算法。但我使用了这三个。

1

从整数颜色开始,进行明显的数学计算(或者如果您能够以16进制思考,则可以从16进制开始)。将每个所需样本的数字添加到颜色中。将颜色整数转换为十六进制,然后将十六进制拆分为RGB。在此代码示例中,最后一种颜色将在分割数内达到十六进制白色(0xffffff)。

# calculate color sample sizes
divisions = 16      # number of desired color samples
total_colors = 256**3-1
color_samples = int((total_colors) / divisions)
print('{0:,} colors in {1:,} parts requires {2:,} per step'.format(total_colors, divisions , color_samples))
# loop to print results
ii = 0
for io in range(0,total_colors,color_samples):
    hex_color = '{0:0>6}'.format(hex(io)[2:])
    rc = hex_color[0:2]  # red 
    gc = hex_color[2:4]  # blue 
    bc = hex_color[4:6]  # green  
    print('{2:>5,} -  {0:>10,} in hex {1} | '.format(io, hex_color, ii), end='')
    print('r-{0} g-{1} b-{2} | '.format(rc, gc, bc), end='')
    print('r-{0:0>3} g-{1:0>3} b-{2:0>3}'.format(int(rc,16), int(gc,16), int(bc,16)))
    ii +=1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接