Graphics 关于生成颜色查找表的基于颜色直方图的方法的问题

Graphics 关于生成颜色查找表的基于颜色直方图的方法的问题,graphics,histogram,rgb,lookup,quantization,Graphics,Histogram,Rgb,Lookup,Quantization,我有一段代码需要符合一篇研究论文中对256项LUT的颜色量化算法的实现,该LUT的24位颜色项来自“总体计数”颜色直方图算法。问题是我不知道作者最初是如何实现他们的直方图算法的——这篇文章有点模棱两可。目前,我基于像素的原始RGB 24位颜色三元组为2^24个整数条目数组编制索引,并增加数组中特定的索引条目。然后,我对直方图进行排序,然后将其组织到一个有效的15位颜色空间中,方法是将512个颜色计数的块放入容器中,并取容器中所有颜色的算术平均值。然后,我将256个平均颜色值(从最大颜色计数开始)

我有一段代码需要符合一篇研究论文中对256项LUT的颜色量化算法的实现,该LUT的24位颜色项来自“总体计数”颜色直方图算法。问题是我不知道作者最初是如何实现他们的直方图算法的——这篇文章有点模棱两可。目前,我基于像素的原始RGB 24位颜色三元组为2^24个整数条目数组编制索引,并增加数组中特定的索引条目。然后,我对直方图进行排序,然后将其组织到一个有效的15位颜色空间中,方法是将512个颜色计数的块放入容器中,并取容器中所有颜色的算术平均值。然后,我将256个平均颜色值(从最大颜色计数开始)按颜色计数的降序填充到256个条目的24位颜色LUT中。虽然产量很令人失望,但质量很低。我知道矢量量化或类似中值切割的东西会更好,但我只能用直方图来做。我用谷歌搜索了大量的“人口计数”直方图算法,但没有一个搜索结果是非常有用的

作为参考,我将包括原始512x512像素24位彩色图像及其基于直方图的彩色LUT对应物:

如果有人能提供一些关于在哪里寻找正确算法的想法或建议,我将非常感激

谢谢

jdb2

试试这个,它也是基于直方图颜色量化的,与您的方法非常相似,但它直接从15位颜色创建直方图以节省空间,不使用容器,而是按出现次数对颜色进行排序,并在调色板阈值中使用与已使用颜色的最小距离,以避免几乎重复的颜色。。。几年前我为我的GIF编码器库开发了它

如果我将此作为输入(转换为jpg):

在上面使用我的algo算法而不抖动我得到了这个结果:

启用抖动后,我得到了以下结果:

正如你在猫耳朵上看到的,抖动要好得多,但即使没有抖动,结果也比你的好得多

然而,随着时间的推移,调色板计算代码(从链接答案中发布的代码)有点演变为(C++):

void gif::compute_palete0()
{
整数x,y,r0,g0,b0,r,g,b,a,aa,c,e,hists;
德沃德一世,i0,cc;
并集{dworddd;字节db[4];}c0,c1;
德沃德·希斯[32768];
DWORD idx[32768];
//15位直方图
对于(x=0;x>6)和0x3E0)|((cc>>9)和0x7C00);
如果(他的[cc]尝试这也是基于直方图颜色量化的,与您的方法非常相似,但它直接从15位颜色创建直方图以节省空间,不使用存储箱,而是按出现次数对颜色进行排序,并使用调色板阈值中已用颜色的最小距离,以避免几乎重复的颜色…我为我的GIF enc开发了它几年前的奥德里布

如果我将此作为输入(转换为jpg):

在上面使用我的algo算法而不抖动我得到了这个结果:

启用抖动后,我得到了以下结果:

正如你在猫耳朵上看到的,抖动要好得多,但即使没有抖动,结果也比你的好得多

然而,随着时间的推移,调色板计算代码(从链接答案中发布的代码)有点演变为(C++):

void gif::compute_palete0()
{
整数x,y,r0,g0,b0,r,g,b,a,aa,c,e,hists;
德沃德一世,i0,cc;
并集{dworddd;字节db[4];}c0,c1;
德沃德·希斯[32768];
DWORD idx[32768];
//15位直方图
对于(x=0;x>6)和0x3E0)|((cc>>9)和0x7C00);

如果(他的[cc]我的问题太长,无法放入评论框,那么我将不得不将其拆分。这是第1部分:---我使用的是ANSI C中的FreeImage库,因此我不必处理加载和保存图像文件的细节。从你的参考文章中,我有几个问题:“转换为15位rgb”我已经可以很容易地做到这一点,我的代码使用每像素15位的颜色量化创建调试图像,看起来很不错。“做一个直方图”什么类型?(在注释的第2部分继续…(注释第2部分)“15位rgb导致32768个条目,所以创建2个数组他的[32768]是像素计数(直方图)idx[32768]是索引=颜色值”在我的代码中,有一个结构可以保持与颜色值关联的颜色计数。我不清楚为什么要使用两个数组。“在计数颜色时,确保计数器在使用低位计数或高分辨率时不会溢出”,我通过索引2^24条目数组并增加索引颜色的计数来计数颜色。(在注释的第3部分继续…)(注释第3部分)“对数组进行重新排序,使his[]中的零位于数组的末尾”我不太确定我在这里是否跟得上你。你的意思是对数组进行排序吗?”还要计算his[]中的非零项,并将其称为hists“根据其设计的性质,我在代码中已经这样做了。”(索引)sort hist[],idx[]so hist[]按降序排列;“不太确定您在这里说什么。”创建N调色板“在我的情况下,N将是256,并且,这是图像质量严重降低的阶段。(在注释第4部分中继续…(注释第4部分)“采用颜色idx[i](i={0,1,2,3,…,hists-1})然后查看调色板中是否没有类似的颜色。如果是,则忽略此颜色(将其设置为最接近的颜色),否则将其添加到调色板中。如果达到N个颜色,请停止“我已经使用平方欧几里德距离度量进行了此操作--虽然粗糙但功能强大。“创建颜色映射”请注意,非常确定您在这里的意思。“因此,选择每种颜色,并在调色板中找到最接近的颜色(这可以在步骤5中部分完成)。我再次称此表为RECLOR[32][32][32]”,但不太清楚您的意思。“RECLOR图像”?:/@jdb2,当您执行15位hi时