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;
}
}
多是浮點運算,可以將參數轉換成整型運算,速度會提升不少。