图像颜色空间转换--RGB to Lαβ

Lαβ 空间是作者在文章《color transfer between images》中于2001年提出来的,该空间相比于RGB空间的优点是三通道相关性很小,缺点是计算量稍大,RGB转到Lαβ 空间是一个非线性的过程,具体Lαβ的介绍以及公式这里就不详细说了,网上一大堆,这里贴出这两个空间的相互转换公式:

void cvtRGB2Lαβ(float_t* pDstL, float_t* pDstA, float_t* pDstB, uint8_t* pSrcR, uint8_t* pSrcG, uint8_t* pSrcB, 
                                        int32_t width, int32_t height, int64_t strideS, int64_t strideD)
{
    uint8_t* srcR = pSrcR;
    uint8_t* srcG = pSrcG;
    uint8_t* srcB = pSrcB;
    float_t* dstL = pDstL;
    float_t* dstA = pDstA;
    float_t* dstB = pDstB;
    float_t  factor = 1.f / log(10.f);
    float_t  fsqrt2  = 1.f / sqrt(2.f);
    float_t  fsqrt3  = 1.f / sqrt(3.f);
    float_t  fsqrt6  = 1.f / sqrt(6.f);

    for (int32_t h = 0; h < height; h++)
    {
        for (int32_t w = 0; w < width; w++)
        {
            int32_t R = srcR[w];
            int32_t G = srcG[w];
            int32_t B = srcB[w];
            float_t L = 0.3811f*R + 0.5783f*G + 0.0402f*B + 0.1f;
            float_t M = 0.1967f*R + 0.7244f*G + 0.0782f*B + 0.1f;
            float_t S = 0.0241f*R + 0.1288f*G + 0.8444f*B + 0.1f;

            L = factor * log(L);
            M = factor * log(M);
            S = factor * log(S);

            dstL[w] = fsqrt3 * (L + M + S);
            dstA[w] = fsqrt6 * (L + M - 2*S);
            dstB[w] = fsqrt2 * (L - M);
        }
        srcR += strideS;
        srcG += strideS;
        srcB += strideS;
        dstL += strideD;
        dstA += strideD;
        dstB += strideD;
    }
}

void cvtLαβ2RGB(uint8_t* pDstR, uint8_t* pDstG, uint8_t* pDstB, float_t*pSrcL, float_t* pSrcA, float_t* pSrcB,
                                        int32_t width, int32_t height, int64_t strideS, int64_t strideD)
{
    float_t* srcL = pSrcL;
    float_t* srcA = pSrcA;
    float_t* srcB = pSrcB;
    uint8_t* dstR = pDstR;
    uint8_t* dstG = pDstG;
    uint8_t* dstB = pDstB;

    for (int32_t h = 0; h < height; h++)
    {
        for (int32_t w = 0; w < width; w++)
        {
            float_t L  = srcL[w] / sqrt(3.f);
            float_t A  = srcA[w] / sqrt(6.f); 
            float_t B  = srcB[w] / sqrt(2.f);
            float_t L1 = L + A + B;
            float_t M  = L + A - B;
            float_t S  = L - 2 * A;

            L1 = pow(10, L1);
            M  = pow(10, M);
            S  = pow(10, S);

            int32_t tmpR = static_cast<int32_t>(( 4.4679*L1 - 3.5873*M + 0.1193*S));
            int32_t tmpG = static_cast<int32_t>((-1.2186*L1 + 2.3809*M - 0.1624*S));
            int32_t tmpB = static_cast<int32_t>(( 0.0497*L1 - 0.2439*M + 1.2045*S));

            dstR[w] = tmpR > 255 ? 255 : tmpR < 0 ? 0 : tmpR;
            dstG[w] = tmpG > 255 ? 255 : tmpG < 0 ? 0 : tmpG;
            dstB[w] = tmpB > 255 ? 255 : tmpB < 0 ? 0 : tmpB;
        }
        srcL += strideS;
        srcA += strideS;
        srcB += strideS;
        dstR += strideD;
        dstG += strideD;
        dstB += strideD;
    }
}

多是浮点运算,可以将参数转换成整型运算,速度会提升不少。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值