http://blog.csdn.net/scarecrow_wiscom/article/details/9795715
一节描述了Matlab自带的sRGB2lab的实现过程,OpenCV版本的RGB2Lab是有稍微差别的,
这里只给出Matlab的语言实现:
function [L, a, b] = sRGB2LabOpenCV(sR, sG, sB)
% SRGB2LAB convert sRGB to CIELAB (OpenCV implemention).
%
if isfloat(sR)
error('Initial image must be Uint8 type!');
end
if nargin == 1
sB = sR(:,:,3);
sG = sR(:,:,2);
sR = sR(:,:,1);
end
[M, N] = size(sR);
s = M * N;
sRL = reshape(sR, 1, s);
sGL = reshape(sG, 1, s);
sBL = reshape(sB, 1, s);
lab_shift = 12;
lab_shift2 = 15;
persistent sRGBGammaTab_b labCbrtTab_b coeffMatD65_c;
% Calculate gamma correction table
if isempty(sRGBGammaTab_b)
nLevel = 256;
sRGBGammaTab_b = zeros(nLevel, 1);
for ii = 0 : nLevel-1
x = ii/255;
if x < 0.04045
sRGBGammaTab_b(ii+1) = uint16( 255*8*(x / 12.92) );
else
sRGBGammaTab_b(ii+1) = uint16( 255*8*(((x+0.055)/1.055)^(2.4)) );
end
end
end
% Calculate Lab cubic root table
if isempty(labCbrtTab_b)
labCbrtLength = nLevel*3/2*8;
labCbrtTab_b = zeros(labCbrtLength, 1);
for ii = 0 : labCbrtLength-1
x = ii / ((nLevel-1)*8);
if x < 0.008856
labCbrtTab_b(ii+1) = double (uint16(2^lab_shift2*(x*7.787 + 0.13793103448275862)) );
else
labCbrtTab_b(ii+1) = double (uint16(2^lab_shift2*(x^(1/3))) );
end
end
end
% Calculate transform matrix coefficient
if isempty(coeffMatD65_c)
wp = [0.950456 1.0 1.088754]; % D65 white point reference
scale_wp = 2^12 ./ wp;
coeffMatD65 = [0.412453 0.357580 0.180423;
0.212671 0.715160 0.072169;
0.019334 0.119193 0.950227]; % D65
coeffMatD65_c = floor(bsxfun(@times, coeffMatD65, scale_wp'));
end
% Get lab data
Lscale = double( int32((116*255+50)/100) );
Lshift = double( int32(-((16*255*2^15 + 50)/100)) );
deScale = @(x, n) floor( (2.0^(n-1)+x)./(2.0^n) );
rValue = sRGBGammaTab_b(sRL+1);
gValue = sRGBGammaTab_b(sGL+1);
bValue = sRGBGammaTab_b(sBL+1);
fX = labCbrtTab_b(deScale(rValue*coeffMatD65_c(1, 1) + ...
gValue*coeffMatD65_c(1, 2) + ...
bValue*coeffMatD65_c(1, 3), lab_shift) + 1);
fY = labCbrtTab_b(deScale(rValue*coeffMatD65_c(2, 1) + ...
gValue*coeffMatD65_c(2, 2) + ...
bValue*coeffMatD65_c(2, 3), lab_shift) + 1);
fZ = labCbrtTab_b(deScale(rValue*coeffMatD65_c(3, 1) + ...
gValue*coeffMatD65_c(3, 2) + ...
bValue*coeffMatD65_c(3, 3), lab_shift) + 1);
L = reshape(uint8(deScale( Lscale*fY + Lshift, lab_shift2)), M, N);
a = reshape(uint8(deScale( 500*(fX - fY) + 128*2^lab_shift2, lab_shift2)), M, N);
b = reshape(uint8(deScale( 200*(fY - fZ) + 128*2^lab_shift2, lab_shift2)), M, N);
if nargout < 2
L = cat(3, L, a, b);
end
另外:在做OpenCV颜色空间转换的时候,要注意转换后的L、A、B通道的布局顺序,不一定是你认为的那样哦!