我编写了一个程序,用于将图像转换为自定义文件格式,该格式使用 30 种特定颜色的有限调色板。
在我的应用程序中,我提供了在 RGB 或 YUV 色彩空间中工作的选项以及以下选项:Sierra、Jarvis 或 Floyd-Steinberg 抖动。
但是我注意到 Photoshop 的保存到网络功能以及使用颜色表来限制调色板的效果比我的程序要好得多。
所以我想改进我的应用程序以获得更好的结果。
现在,以 Floyd-Steinberg 抖动为例,我基本上使用的是这个伪代码
for each y from top to bottom
for each x from left to right
oldpixel := pixel[x][y]
newpixel := find_closest_palette_color(oldpixel)
pixel[x][y] := newpixel
quant_error := oldpixel - newpixel
pixel[x+1][y ] := pixel[x+1][y ] + quant_error * 7/16
pixel[x-1][y+1] := pixel[x-1][y+1] + quant_error * 3/16
pixel[x ][y+1] := pixel[x ][y+1] + quant_error * 5/16
pixel[x+1][y+1] := pixel[x+1][y+1] + quant_error * 1/16
我的像素以 RGB 格式存储,为了找到最接近的调色板颜色,我使用 RGB/YUV 中的欧几里得距离。
我一直在阅读有关 CIE94 和 CIEDE2000 色差算法的内容,这些算法应该更适合我的“find_closest_palette_color”函数。
要进行这些计算,我必须将 RGB 颜色空间转换为 CIELab 颜色空间。在分布抖动算法中的错误时,我是否也可以使用 CIELab:
是的,事实上 Lab 更适合这个目的,因为 Lab 中颜色之间的欧几里得距离反映了人类感知颜色之间的距离,而 RGB 中的距离则不然。
使用缓存将整个图像转换为 CIELab 色彩空间。
对源图像的像素进行聚类,以使用 CIE76 和 CIEDE2000 的比率找到最佳调色板。
计算 CIELab 颜色空间(YUV 而不是 RGB)中的误差。
借助蓝噪声分布混合并匹配误差。
使用广义希尔伯特(“吉尔伯特”)空间填充曲线 O(n) 代替 Floyd-Steinberg 抖动 O(n2) 通过最小化 RGB 中的 MSE。