RGB转Lab的那些事(二)

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通道的布局顺序,不一定是你认为的那样哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值