免责声明:临时答案(即没有任何文档支持):
“256”是 bin 大小的常用数字,因为程序员喜欢圆形数字——它适合单个字节。而“180”是因为 HSB 圆是“360 [度]”,但“360”不适合单个字节。
对于许多图像格式,RGB 值的范围限制为每个通道 0..255 - 总共 3 个字节。为了存储相同数量的数据(忽略任何转换为另一种颜色模型的伪影),饱和度和亮度通常也以单个字节表示。对色调也可以这样做,通过将原始范围 0..359(因为色调通常表示为 HSB 色轮上的度数)到字节范围 0..255 中。但是,可能因为使用接近原始 360° 全圆的数字进行计算更容易,所以范围被裁剪为 0..179。这样,该值可以存储到单个字节中(因此“HSB”使用与“RGB”一样多的内存)并且可以简单地转换回(接近)其原始值——乘以 2。显然,坚持存储空间胜过保真度。
给定 S 和 B 的 256 个值以及 H 的 180 个值,您最终会得到 256*256*180 = 11,796,480 种颜色的颜色空间。要检查颜色的数量,您可以构建一个histogram:一个数组,您可以在其中读取特定颜色或颜色范围内的像素总数。在此处使用颜色范围,而不是实际值,可以显着降低内存需求。
对于 RGB 彩色图像,颜色分布相当均匀,您可以将每个通道向下移动一定数量的位。这就是从 24 位“真彩”RGB 到 15 位 RGB“高彩”空间的直接转换的工作原理:每个通道除以 8,将 256 个值减少到 32(每个通道 5 位)。转换为 16 位高色彩 RGB 空间的工作方式相同;在 15 位转换中剩下的位分配给 green。因此,绿色的颜色范围加倍,这很有用,因为人眼对绿色阴影的感知比对其他两种原色的感知能力更强。
当输入图像中的颜色不均匀分布时,情况会变得更加复杂。一个天真的解决方案是创建一个 [256][256][256] 的数组,将所有初始化为零,然后用图像的颜色填充数组,最后对它们进行排序。还有更好的选择——让我在这里查阅我的旧计算机图形[1]。等等。
13.4 再现颜色提到了 Heckbert 的两种不同方法的名称(Color Image Quantization for Frame Buffer Display,SIGGRAPH 82):流行 和 median-cut 算法。 (不幸的是,这就是他们关于这个话题的全部内容。我认为可以通过谷歌搜索两者的有效代码。)
粗略的猜测:
每个 bin (H,S,B) 的大小应该反映在您尝试使用它的目的上。例如,This older SO question 为 hue 使用了一个大的 bin——颜色被认为是最重要的——并且饱和度和亮度只有 3 个不同的值。因此,具有一些柔和区域的明亮图像(例如,漫画书)将在此直方图中提供良好的传播,但真彩色照片不会那么多。
主要限制是 bin 大小相互相乘时应使用相当少量的内存,但要覆盖足够的每个组件以均匀填充。也许一些试错在这里起作用。您最初可以将所有 H、S 和 B 分量均匀分布在直方图中的可用内存中,并处理图像的一小部分;比如说,水平和垂直方向的 4 个像素中的 1 个。如果您发现其中一个组件箱装得太快,而其他组件箱则保持不变,请调整范围并重新启动。
如果您需要对多张图片进行分析,请确保它们的色域都相同。您不能期望合理的 bin 大小适用于所有类型的图像;你最终会得到一个均匀分布,所有匹配都只是马马虎虎。
[1] 计算机图形学。原则和实践。 (1997) J.D. Foley, A. van Dam, S.K. Feiner 和 J.F. Hughes,第 2 版,马萨诸塞州雷丁市:Addison-Wesley。