当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++基础入门教程

RGB色彩变换到Lab空间代码

    这是两个函数,CIE标准的变换;和Adobe的不一样

    Step1:
    XYZ to RGB (采用 D65 白点):

       [ R ]   [  3.240479 -1.537150 -0.498535 ]   [ X ]
       [ G ] = [ -0.969256  1.875992  0.041556 ] * [ Y ]
       [ B ]   [  0.055648 -0.204043  1.057311 ]   [ Z ].

        R, G, B 在 [0,1].

    逆变换:

       [ X ]   [  0.412453  0.357580  0.180423 ]   [ R ]
       [ Y ] = [  0.212671  0.715160  0.072169 ] * [ G ]
       [ Z ]   [  0.019334  0.119193  0.950227 ]   [ B ]

    Step2:
    XYZ to CIE L*a*b* (CIELAB) & CIELAB to XYZ

    L* = 116 * (Y/Yn)1/3 - 16    若 Y/Yn > 0.008856
    L* = 903.3 * Y/Yn            其他

    a* = 500 * ( f(X/Xn) - f(Y/Yn) )
    b* = 200 * ( f(Y/Yn) - f(Z/Zn) )
        其中 f(t) = t1/3                 若 t > 0.008856
             f(t) = 7.787 * t + 16/116   其他

    其中Xn, Yn 和 Zn是参考白的三刺激值。

    逆变换( Y/Yn > 0.008856) :

    X = Xn * ( P + a* / 500 ) 3
    Y = Yn * P 3
    Z = Zn * ( P - b* / 200 ) 3
        其中 P = (L* + 16) / 116
    ====================================================================


    这是我的代码:按照CIE走的,出来的结果和大家常用的PhotoShop的是不一样的;

    不过有一种算法的计算结果很逼近photoshop的,再整理出来吧;


    double BLACK = 20;
    double YELLOW = 70;
    void RGB2Lab(double R, double G, double B, double &L, double &a, double &b)
    {
     double X, Y, Z, fX, fY, fZ;

        X = 0.412453*R + 0.357580*G + 0.180423*B;
        Y = 0.212671*R + 0.715160*G + 0.072169*B;
        Z = 0.019334*R + 0.119193*G + 0.950227*B;

        X /= (255 * 0.950456);
        Y /=  255;
        Z /= (255 * 1.088754);

        if (Y > 0.008856)
        {
         fY = pow(Y, 1.0/3.0);
         L = 116.0*fY - 16.0;
        }
        else
        {
         fY = 7.787*Y + 16.0/116.0;
         L = 903.3*Y;
        }

        if (X > 0.008856)
         fX = pow(X, 1.0/3.0);
        else
         fX = 7.787*X + 16.0/116.0;

        if (Z > 0.008856)
         fZ = pow(Z, 1.0/3.0);
        else
         fZ = 7.787*Z + 16.0/116.0;

        a = 500.0*(fX - fY);
        b = 200.0*(fY - fZ);

        if (L < BLACK)
        {
         a *= exp((L - BLACK) / (BLACK / 4));
         b *= exp((L - BLACK) / (BLACK / 4));
         L = BLACK;
        }
        if (b > YELLOW)
         b = YELLOW;


    }


    void Lab2RGB(double L, double a, double b, double &R, double &G, double &B)
    {
     double X, Y, Z, fX, fY, fZ;
     double RR, GG, BB;

        fY = pow((L + 16.0) / 116.0, 3.0);
        if (fY < 0.008856)
         fY = L / 903.3;
        Y = fY;

        if (fY > 0.008856)
         fY = pow(fY, 1.0/3.0);
        else
         fY = 7.787 * fY + 16.0/116.0;

        fX = a / 500.0 + fY;
        if (fX > 0.206893)
         X = pow(fX, 3.0);
        else
         X = (fX - 16.0/116.0) / 7.787;

        fZ = fY - b /200.0;
        if (fZ > 0.206893)
         Z = pow(fZ, 3.0);
        else
         Z = (fZ - 16.0/116.0) / 7.787;

        X *= (0.950456 * 255);
        Y *=             255;
        Z *= (1.088754 * 255);

        RR =  3.240479*X - 1.537150*Y - 0.498535*Z;
        GG = -0.969256*X + 1.875992*Y + 0.041556*Z;
        BB =  0.055648*X - 0.204043*Y + 1.057311*Z;

        R = (float)(RR < 0 ? 0 : RR > 255 ? 255 : RR);
        G = (float)(GG < 0 ? 0 : GG > 255 ? 255 : GG);
        B = (float)(BB < 0 ? 0 : BB > 255 ? 255 : BB);
    }

 

    ======================================================

 

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接