首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HCL颜色为RGB和向后

HCL颜色为RGB和向后
EN

Stack Overflow用户
提问于 2011-09-23 14:31:50
回答 6查看 15.5K关注 0票数 22

我需要一个将HCL颜色转换为RGB和向后RGB转换为HCL的算法,记住这些颜色空间有不同的色域(我需要将HCL颜色限制到那些可以在RGB颜色空间中再现的颜色)。这方面的算法是什么(该算法打算在本机只支持RGB颜色的沃尔夫勒姆中实现)?我没有使用色彩空间的经验。

P.S.关于HCL颜色的一些文章:

M. Sarifuddin (2005年)。一种新的基于内容的图像和视频检索的具有关联颜色相似性度量的感知均匀颜色空间。

Zeileis,Hornik和Murrell (2009年):Escaping :为统计图形//计算统计和数据分析选择颜色第53卷,第9期,2009年7月1日,第3259至3270页

UPDATE:UPDATE:如乔纳森·詹森所指出的,在上述两篇文章中,不同的颜色空间被称为"HCL":“第二篇文章使用的是L_C_h(uv),它与L_u_v*相同,但用极坐标描述,其中h(uv)是u*和v*坐标的角度,C*是该向量的大小”。因此,实际上,我需要一个算法来将RGB转换为L_u_v*并向后转换。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-09-26 20:59:48

我也只是在了解HCL颜色空间。但是,问题中这两篇文章中使用的颜色空间似乎是不同的颜色空间。

第二篇文章使用L* C* h(uv),它与L* u* v*相同,但用极坐标描述,其中h(uv)是u*的角,v*是该矢量的大小。

第一篇文章中的LCH颜色空间似乎描述了另一种颜色空间,而不是使用更多的算法转换。这里还有第一篇论文的另一个版本:http://isjd.pdii.lipi.go.id/admin/jurnal/14209102121.pdf

如果您打算使用CIE *u*v*,则首先需要将sRGB转换为CIE,然后转换为CIE *u*v*。在大多数情况下,RGB实际上是指sRGB,因此不需要从RGB转换为sRGB。

所有需要的源代码

关于如何转换到XYZ的好文章

Nice在线转换器

但是我不能回答你关于如何将颜色限制在sRGB空间的问题。在转换后,您可以丢弃RGB颜色,这些颜色超出了0到1的范围。仅仅是夹紧颜色就会产生非常奇怪的结果。尝试转到转换器并输入颜色RGB 0 0 255并转换为L*a*b* (类似于L*u*v*),然后增加L*以表示70并将其转换回来,结果肯定不再是蓝色了。

编辑:更正URL编辑:将另一个答案合并到这个答案中

票数 13
EN

Stack Overflow用户

发布于 2012-08-15 12:29:18

HCL是一个非常通用的名字,有很多种方法可以有色调、色度和亮度。例如,Chroma.js有一个叫做HCL的东西,它是极coord转换的实验室(当您查看实际代码时)。其他实现,即使是从同一站点链接的实现,也使用Polar。由于您可以简单地借用L因子,并通过转换为极坐标来导出色调,这两种方法都是获得这三种元素的有效方法。由于混乱因素,称它们为极地实验室和极地Luv要好得多。

M.Sarifuddin(2005)的算法不是Polar或Polar,在计算上更简单(不需要首先导出Lab或Luv空间),而且实际上可能更好。报纸上有些东西似乎是不对的。例如,将欧氏距离应用于CIE L*C*H*颜色空间。Hue的使用意味着它必然是圆的,只要把这个数字塞到A²+B²+C²上就会产生问题。同样,将基于颜色的颜色空间应用到D94或D00中也是如此,因为这是一种距离算法,并内置了特定于Lab颜色空间的校正。除非我遗漏了什么,否则我会忽略图6-8。我质疑图形中的拒绝公差。您可以设置一个较低的阈值并做得更好,并且颜色空间之间的数字没有标准化。无论如何,尽管论文中有一些看似的缺陷,但所描述的算法还是值得一试的。如果不太重要的话,你可能想在RGB上做欧几里德。但是,如果你在附近买颜色距离算法,给你。

下面是M.Sarifuddin给出的用Java实现的HCL。在反复阅读了这篇论文之后,我不得不得出这样的结论: distance_hcl例程中色调的变化使距离的比例在0.16到180.16之间。这是一个如此深刻的因素,它几乎不可能是正确的。使配色变得糟糕。我把纸上的线注释掉了,用了一条只有Al因子的线。常数~1.4因子的定标发光并不会使它无法使用。如果没有标度因子,它最终将与自行车距离相同。

本文对http://w3.uqo.ca/missaoui/Publications/TRColorSpace.zip进行了修正和改进。

代码语言:javascript
复制
static final public double Y0 = 100;
static final public double gamma = 3;
static final public double Al = 1.4456;
static final public double Ach_inc = 0.16;

public void rgb2hcl(double[] returnarray, int r, int g, int b) {
    double min = Math.min(Math.min(r, g), b);
    double max = Math.max(Math.max(r, g), b);
    if (max == 0) {
        returnarray[0] = 0;
        returnarray[1] = 0;
        returnarray[2] = 0;
        return;
    }

    double alpha = (min / max) / Y0;
    double Q = Math.exp(alpha * gamma);
    double rg = r - g;
    double gb = g - b;
    double br = b - r;
    double L = ((Q * max) + ((1 - Q) * min)) / 2;
    double C = Q * (Math.abs(rg) + Math.abs(gb) + Math.abs(br)) / 3;
    double H = Math.toDegrees(Math.atan2(gb, rg));

    /*
    //the formulae given in paper, don't work.
    if (rg >= 0 && gb >= 0) {
        H = 2 * H / 3;
    } else if (rg >= 0 && gb < 0) {
        H = 4 * H / 3;
    } else if (rg < 0 && gb >= 0) {
        H = 180 + 4 * H / 3;
    } else if (rg < 0 && gb < 0) {
        H = 2 * H / 3 - 180;
    } // 180 causes the parts to overlap (green == red) and it oddly crumples up bits of the hue for no good reason. 2/3H and 4/3H expanding and contracting quandrants.
    */

    if (rg <  0) {
        if (gb >= 0) H = 90 + H;
        else { H = H - 90; }
    } //works


    returnarray[0] = H;
    returnarray[1] = C;
    returnarray[2] = L;
}

public double cycldistance(double[] hcl1, double[] hcl2) {
    double dL = hcl1[2] - hcl2[2];
    double dH = Math.abs(hcl1[0] - hcl2[0]);
    double C1 = hcl1[1];
    double C2 = hcl2[1];
    return Math.sqrt(dL*dL + C1*C1 + C2*C2 - 2*C1*C2*Math.cos(Math.toRadians(dH)));
}

public double distance_hcl(double[] hcl1, double[] hcl2) {
    double c1 = hcl1[1];
    double c2 = hcl2[1];
    double Dh = Math.abs(hcl1[0] - hcl2[0]);
    if (Dh > 180) Dh = 360 - Dh;
    double Ach = Dh + Ach_inc;
    double AlDl = Al * Math.abs(hcl1[2] - hcl2[2]);
    return Math.sqrt(AlDl * AlDl + (c1 * c1 + c2 * c2 - 2 * c1 * c2 * Math.cos(Math.toRadians(Dh))));
    //return Math.sqrt(AlDl * AlDl + Ach * (c1 * c1 + c2 * c2 - 2 * c1 * c2 * Math.cos(Math.toRadians(Dh))));
}
票数 8
EN

Stack Overflow用户

发布于 2011-09-23 15:02:48

我对很多颜色空间都很熟悉,但是这个对我来说是新的。唉,数学的ColorConvert也不知道。

我找到了一个rgb2hcl例程这里,但没有另一个例程。

一个更全面的颜色空间转换包可以找到这里。它似乎能够进行各种颜色空间的转换。在colorspace_1.1-0.tar.gz\colorspace_1.1-0.tar\colorspace\src.中查找文件#en0#space.c请注意,HCL在此包中称为PolarLUV。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7530627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档