首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JzAzBz java实现精度

JzAzBz java实现精度
EN

Stack Overflow用户
提问于 2018-03-24 12:02:52
回答 1查看 262关注 0票数 1

我做了一个java实现了新的感知一致的颜色空间JzAzBz。OSA出版物是:https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-25-13-15131&id=368272

我的java代码是:

代码语言:javascript
复制
private double b = 1.15;
private double g = 0.66;
private double c1 = 3424 / Math.pow(2, 12);
private double c2 = 2413 / Math.pow(2, 7);
private double c3 = 2392 / Math.pow(2, 7);
private double n = 2610 / Math.pow(2, 14);
private double p = 1.7 * 2523 / Math.pow(2, 5);
private double d = -0.56;
private double d0 = 1.6295499532821566 * Math.pow(10, -11);

public void XYZToJab(double[] xyz, double[] jab) {
    double[] XYZp = new double[3];
    XYZp[0] = b * xyz[0] - ((b - 1) * xyz[2]);
    XYZp[1] = g * xyz[1] - ((g - 1) * xyz[0]);
    XYZp[2] = xyz[2];

    double[] LMS = new double[3];
    LMS[0] = 0.41478972 * XYZp[0] + 0.579999 * XYZp[1] + 0.0146480 * XYZp[2];
    LMS[1] = -0.2015100 * XYZp[0] + 1.120649 * XYZp[1] + 0.0531008 * XYZp[2];
    LMS[2] = -0.0166008 * XYZp[0] + 0.264800 * XYZp[1] + 0.6684799 * XYZp[2];

    double[] LMSp = new double[3];
    for (int i = 0; i < 3; i++) {
        LMSp[i] = Math.pow((c1 + c2 * Math.pow((LMS[i] / 10000.0), n)) / (1 + c3 * Math.pow((LMS[i] / 10000.0), n)), p);
    }

    double[] Iab = new double[3];
    Iab[0] = 0.5 * LMSp[0] + 0.5 * LMSp[1];
    Iab[1] = 3.524000 * LMSp[0] - 4.066708 * LMSp[1] + 0.542708 * LMSp[2];
    Iab[2] = 0.199076 * LMSp[0] + 1.096799 * LMSp[1] - 1.295875 * LMSp[2];

    jab[0] = (((1 + d) * Iab[0]) / (1 + d * Iab[0])) - d0;
    jab[1] = Iab[1];
    jab[2] = Iab[2];
}

public void JabToXYZ(double[] jab, double[] xyz) {

    double[] Iab = new double[3];
    Iab[0] = (jab[0] + d0) / (1 + d - d * (jab[0] + d0));
    Iab[1] = jab[1];
    Iab[2] = jab[2];

    double[] LMSp = new double[3];
    LMSp[0] = 1.0 * Iab[0] + 0.13860504 * Iab[1] + 0.05804732 * Iab[2];
    LMSp[1] = 1.0 * Iab[0] - 0.13860504 * Iab[1] - 0.05804732 * Iab[2];
    LMSp[2] = 1.0 * Iab[0] - 0.09601924 * Iab[1] - 0.81189190 * Iab[2];

    double[] LMS = new double[3];
    for (int i = 0; i < 3; i++) {
        LMS[i] = 10000 * Math.pow((c1 - Math.pow(LMSp[i], 1 / p)) / ((c3 * Math.pow(LMSp[i], 1 / p)) - c2), 1 / n);
    }

    double[] XYZp = new double[3];
    XYZp[0] = 1.92422644 * LMS[0] - 1.00479231 * LMS[1] + 0.03765140 * LMS[2];
    XYZp[1] = 0.35031676 * LMS[0] + 0.72648119 * LMS[1] - 0.06538442 * LMS[2];
    XYZp[2] = -0.09098281 * LMS[0] - 0.31272829 * LMS[1] + 1.52276656 * LMS[2];

    xyz[0] = (XYZp[0] + (b - 1) * XYZp[2]) / b;
    xyz[1] = (XYZp[1] + (g - 1) * XYZp[0]) / g;
    xyz[2] = XYZp[2];
}

当我测试它运行XYZToJab,然后是JabToXYZ时,X和Z得到了很好的精度(增量阶数为E-9),而对于Y,精度很差(增量阶为1-5%)。

有人能帮我吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-24 20:28:11

实现几乎是正确的:错误在JabToXYZ中,应该将最后一行的前一行更改为

代码语言:javascript
复制
(XYZp[1] + (g - 1) * XYZp[0]) / g;

代码语言:javascript
复制
(XYZp[1] + (g - 1) * xyz[0]) / g;

然而,在JabToXYZ函数中使用四舍五入的逆矩阵到小数点6位的事实将阻止您得到一个干净的反转。您应该尝试以完全双精度的方式计算逆:

代码语言:javascript
复制
>>> import numpy as np
>>> np.set_printoptions(formatter={'float': '{:0.15f}'.format})
>>> import colour.models.jzazbz
>>> colour.models.jzazbz.JZAZBZ_IZAZBZ_TO_LMS_P_MATRIX
array([[1.000000000000000, 0.138605043271539, 0.058047316156119],
       [1.000000000000000, -0.138605043271539, -0.058047316156119],
       [1.000000000000000, -0.096019242026319, -0.811891896056039]])
>>> colour.models.jzazbz.JZAZBZ_LMS_TO_XYZ_MATRIX
array([[1.924226435787607, -1.004792312595365, 0.037651404030618],
       [0.350316762094999, 0.726481193931655, -0.065384422948085],
       [-0.090982810982848, -0.312728290523074, 1.522766561305260]])
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49464451

复制
相关文章

相似问题

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