圖像顏色空間轉換--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;
    }
}

多是浮點運算,可以將參數轉換成整型運算,速度會提升不少。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章