The fusion matrixes for Color space

本文详细介绍了不同色彩空间(如YCbCr、YUV等)与RGB之间的转换公式,并提供了从RGB到HSL及HSV颜色模型的算法实现。适用于图像处理、视频编码等领域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[ITU 601: YCbCr <-> RGB]
0    <= Y, R, G, B <= 1
-0.5 <= Cb, Cr     <= 0.5
Y  =  0.299 * R + 0.587 * G + 0.114 * B
Cb = -0.169 * R - 0.331 * G + 0.500 * B
Cr =  0.500 * R - 0.419 * G - 0.081 * B

R  = Y + 0.000 * Cb + 1.403 * Cr
G  = Y - 0.344 * Cb - 0.714 * Cr
B  = Y + 1.773 * Cb + 0.000 * Cr

[ITU 601 Revision: YCbCr <-> RGB]
0 <= Y, Cb, Cr, R, G, B <= 255

Y  =  0.299 * R + 0.587 * G + 0.114 * B
Cb = -0.169 * R - 0.331 * G + 0.499 * B + 128
Cr =  0.499 * R - 0.418 * G - 0.0813 * B + 128

R  = Y + 0.000 * (Cb – 128) + 1.402 * (Cr – 128)
G  = Y - 0.344 * (Cb – 128) - 0.714 * (Cr – 128)
B  = Y + 1.772 * (Cb - 128) + 0.000 * (Cr – 128)


[ITU 709: YCbCr <-> RGB]
0    <= Y, R, G, B <= 1
-0.5 <= Cb, Cr     <= 0.5
Y  =  0.2215 * R + 0.7154 * G + 0.0721 * B
Cb = -0.1145 * R - 0.3855 * G + 0.5000 * B
Cr =  0.5016 * R - 0.4556 * G - 0.0459 * B

R  = Y + 0.0000 * Cb + 1.5701 * Cr
G  = Y - 0.1870 * Cb - 0.4664 * Cr
B  = Y - 1.8556 * Cb + 0.0000 * Cr

[EBU: YUV <-> RGB]
0      <= Y, R, G, B <= 1
-0.436 <= U          <= 0.436
-0.615 <= V          <= 0.615
Y =                    0.299 * R + 0.587 * G + 0.114 * B
U = 0.493 * (B - Y) = -0.147 * R - 0.289 * G + 0.436 * B
V = 0.877 * (R - Y) =  0.615 * R - 0.515 * G - 0.100 * B

R = Y + 0.000 * U + 1.140 * V
G = Y - 0.396 * U - 0.581 * V
B = Y + 2.029 * U + 0.000 * V

[RGB <-> HSL]

Algorithm RGB -> HSL
0 <= R, G, B <= 1
0 <= H       <= 360
0 <= S, L    <= 1

max = MAX( R, G, B )
min = MIN( R, G, B )

1) max = min
h = 0
2) max = R
h = (60 * (G - B) / (max - min) + 360 ) mod 360
3) max = G
h = 60 * (B - R) / (max - min) + 120
4) max = B
h = 60 * (R - G) / (max - min) + 240

L = (max + min) / 2

1) max = min
s = 0;
2) L <= 0.5
s = (max - min) / (max + min) = (max - min) / (2 * L)
3) L > 0.5
s = (max - min) / (2 - (max + min)) = (max - min) / (2 - 2 * L)

Algorithm HSL -> RGB
0 <= R, G, B <= 1
0 <= H       < 360
0 <= S, L    <= 1

1) L < 0.5
Q = L * (L + S)
2) L >= 0.5
Q = L + S - (L * S)

P = 2 * L - Q

Hk = H / 360

Tr = Hk + 1.0 / 3.0
Tg = Hk
Tb = Hk - 1.0 / 3.0

1) Tr < 0
Tr = Tr + 1.0
2) Tr > 1.0
Tr = Tr - 1.0

3) Tg < 0
Tg = Tg + 1.0
4) Tg > 1.0
Tg = Tg - 1.0

5) Tb < 0
Tb = Tb + 1.0
6) Tb > 1.0
Tb = Tb - 1.0

1) Tr < 1.0 / 6.0
Tr = P + ((Q - P) * 6 * Tr)
2) 1.0 / 6.0 <= Tr < 0.5
Tr = Q
3) 0.5 <= Tr < 2.0 / 3.0
Tr = P + ((Q- P) * 6 * (2.0 / 3.0 - Tr))
4) otherwise
Tr = P

5) Tg < 1.0 / 6.0
Tg = P + ((Q - P) * 6 * Tg)
6) 1.0 / 6.0 <= Tg < 0.5
Tg = Q
7) 0.5 <= Tg < 2.0 / 3.0
Tg = P + ((Q- P) * 6 * (2.0 / 3.0 - Tg))
8) otherwise
Tg = P

9) Tb < 1.0 / 6.0
Tb = P + ((Q - P) * 6 * Tb)
10) 1.0 / 6.0 <= Tb < 0.5
Tb = Q
11) 0.5 <= Tb < 2.0 / 3.0
Tb = P + ((Q- P) * 6 * (2.0 / 3.0 - Tb))
12) otherwise
Tb = P

[RGB <-> HSV]

Algorithm RGB -> HSV
0 <= R, G, B <= 1
0 <= H       <= 360
0 <= S, V    <= 1

max = MAX( R, G, B )
min = MIN( R, G, B )

1) max = min
h = 0
2) max = R
h = (60 * (G - B) / (max - min) + 360 ) mod 360
3) max = G
h = 60 * (B - R) / (max - min) + 120
4) max = B
h = 60 * (R - G) / (max - min) + 240

1) max = 0
S = 0
2) otherwise
S = (max - min) / max = 1 - (min / max)

V = max

Algorithm HSV -> RGB
0 <= R, G, B <= 1
0 <= H       < 360
0 <= S, V    <= 1

Hi = INT(H /60.0) mod 6
F  = H / 60.0 - INT(H /60.0)
P  = V * (1 - S)
Q  = V * (1 - F * S)
T  = V * (1 - (1 - F) * S)

1) Hi = 0
R = V
G = T
B = P
2) Hi = 1
R = Q
G = V
B = P
3) Hi = 2
R = P
G = V
B = T
4) Hi = 3
R = P
B = Q
G = V
5) Hi = 4
R = T
G = P
B = V
6) Hi = 5
R = V
G = P
B = Q


[The implementation for converter]

#define I_MACRO_BEGIN                        do {
#define I_MACRO_END                            } while ( 0 )

#define CLIP( v, min, max )                                                                        /
    I_MACRO_BEGIN                                                                                /
    if ( (v) < (min) )                                                                            /
        (v) = (min);                                                                            /
    else if ( (v) > (max) )                                                                        /
        (v) = (max);                                                                            /
    I_MACRO_END

// r, g, b, y, u, v are [0, 255]
// Cb = u
// Cr = v
#define ITU601_REV_RGB2YUV444( r, g, b, y, u, v )                                                /
    I_MACRO_BEGIN                                                                                /
    (y) = (int) (0.299 * (r) + 0.587 * (g) + 0.114 * (b) + 0.5);                                /
    (u) = (int) (-0.169 * (r) - 0.331 * (g) + 0.499 * (b) + 128.5);                                /
    (v) = (int) (0.499 * (r) - 0.418 * (g) - 0.0813 * (b) + 128.5);                                /
    CLIP( y, 0, 255 );                                                                            /
    CLIP( u, 0, 255 );                                                                            /
    CLIP( v, 0, 255 );                                                                            /
    I_MACRO_END

// r, g, b, y, u, v are [0, 255]
// Cb = u
// Cr = v
#define ITU601_REV_YUV4442RGB( y, u, v, r, g, b )                                                /
    I_MACRO_BEGIN                                                                                /
    (r) = (int) ((y) + 1.402 * ((v) - 128) + 0.5);                                                /
    (g) = (int) ((y) - 0.344 * ((u) - 128) - 0.714 * ((v) - 128) + 0.5);                        /
    (b) = (int) ((y) + 1.772 * ((u) - 128) + 0.5);                                                /
    CLIP( r, 0, 255 );                                                                            /
    CLIP( g, 0, 255 );                                                                            /
    CLIP( b, 0, 255 );                                                                            /
    I_MACRO_END

// r, g, b, y are [0, 1]
// u, v are [-0.5, 0.5]
// Cb = u
// Cr = v
#define ITU601_RGB2YUV444( r, g, b, y, u, v )                                                    /
    I_MACRO_BEGIN                                                                                /
    (y) = 0.299 * (r) + 0.587 * (g) + 0.114 * (b);                                                /
    (u) = -0.169 * (r) - 0.331 * (g) + 0.500 * (b);                                                /
    (v) = 0.500 * (r) - 0.419 * (g) - 0.081 * (b);                                                /
    CLIP( y, 0, 1.0 );                                                                            /
    CLIP( u, -0.5, 0.5 );                                                                        /
    CLIP( v, -0.5, 0.5 );                                                                        /
    I_MACRO_END

// r, g, b, y are [0, 1]
// u, v are [-0.5, 0.5]
// Cb = u
// Cr = v
#define ITU601_YUV4442RGB( y, u, v, r, g, b )                                                    /
    I_MACRO_BEGIN                                                                                /
    (r) = (y) + 1.403 * (v);                                                                    /
    (g) = (y) - 0.344 * (u) - 0.714 * (v);                                                        /
    (b) = (y) + 1.773 * (u);                                                                    /
    CLIP( r, 0, 1.0 );                                                                            /
    CLIP( g, 0, 1.0 );                                                                            /
    CLIP( b, 0, 1.0 );                                                                            /
    I_MACRO_END

// r, g, b, y are [0, 1]
// u, v are [-0.5, 0.5]
// Cb = u
// Cr = v
#define ITU709_RGB2YUV444( r, g, b, y, u, v )                                                    /
    I_MACRO_BEGIN                                                                                /
    (y) = 0.2215 * (r) + 0.7154 * (g) + 0.0721 * (b);                                            /
    (u) = -0.1145 * (r) - 0.3855 * (g) + 0.500 * (b);                                            /
    (v) = 0.5016 * (r) - 0.4556 * (g) - 0.0459 * (b);                                            /
    CLIP( y, 0, 1.0 );                                                                            /
    CLIP( u, -0.5, 0.5 );                                                                        /
    CLIP( v, -0.5, 0.5 );                                                                        /
    I_MACRO_END

// r, g, b, y are [0, 1]
// u, v are [-0.5, 0.5]
// Cb = u
// Cr = v
#define ITU709_YUV4442RGB( y, u, v, r, g, b )                                                    /
    I_MACRO_BEGIN                                                                                /
    (r) = (y) + 1.5701 * (v);                                                                    /
    (g) = (y) - 0.1870 * (u) - 0.4664 * (v);                                                    /
    (b) = (y) - 1.8556 * (u);                                                                    /
    CLIP( r, 0, 1.0 );                                                                            /
    CLIP( g, 0, 1.0 );                                                                            /
    CLIP( b, 0, 1.0 );                                                                            /
    I_MACRO_END

// r, g, b are [0, 1]
// h is [0, 360)
// s is [0, 1]
// l is [0, 1]
#define RGB2HSL( r, g, b, h, s, l )                                                                /
    I_MACRO_BEGIN                                                                                /
    if ( (r) == (g) && (g) == (b) )                                                                /
    {                                                                                            /
        (h) = 0;                                                                                /
        (s) = 0;                                                                                /
        (l) = (g);                                                                                /
    }                                                                                            /
    else                                                                                        /
    {                                                                                            /
        float _max;                                                                                /
        float _min;                                                                                /
        if ( (r) > (g) )                                                                        /
        {                                                                                        /
            _min = (g) > (b) ? (b) : (g);                                                        /
            if ( (r) > (b) ) /* r is max */                                                        /
            {                                                                                    /
                _max = (r);                                                                        /
                (h)  = ((int) (60.0 * ((g) - (b)) / ((r) - _min) + 0.5) + 360) % 360;            /
            }                                                                                    /
            else /* b is max */                                                                    /
            {                                                                                    /
                _max = (b);                                                                        /
                (h)  = (int) (60.0 * ((r) - (g)) / ((b) - _min) + 0.5) + 240;                    /
            }                                                                                    /
        }                                                                                        /
        else /* (r) <= (g) */                                                                    /
        {                                                                                        /
            _min = (r) > (b) ? (b) : (r);                                                        /
            if ( (g) > (b) ) /* g is max */                                                        /
            {                                                                                    /
                _max = (g);                                                                        /
                (h)  = (int) (60.0 * ((b) - (r)) / ((g) - _min) + 0.5) + 120;                    /
            }                                                                                    /
            else /* b is max */                                                                    /
            {                                                                                    /
                _max = (b);                                                                        /
                (h)  = (int) (60.0 * ((r) - (g)) / ((b) - _min) + 0.5) + 240;                    /
            }                                                                                    /
        }                                                                                        /
        (l) = 0.5 * (_max + _min);                                                                /
        if ( (l) > 0.5 )                                                                        /
        {                                                                                        /
            (s) = (float) (_max - _min) / (2.0 - (_max + _min));                                /
        }                                                                                        /
        else                                                                                    /
        {                                                                                        /
            (s) = (float) (_max - _min) / (float) (_max + _min);                                /
        }                                                                                        /
    }                                                                                            /
    I_MACRO_END

#define II_HSL2RGB( p, q, tc )                                                                    /
    I_MACRO_BEGIN                                                                                /
    if ( (tc) < 1.0 / 6.0 )                                                                        /
    {                                                                                            /
        (tc) = (p) + ((q) - (p)) * 6.0 * (tc);                                                    /
    }                                                                                            /
    else if ( (tc) < 1.0 / 2.0 )                                                                /
    {                                                                                            /
        (tc) = (q);                                                                                /
    }                                                                                            /
    else if ( (tc) < 2.0 / 3.0 )                                                                /
    {                                                                                            /
        (tc) = (p) + ((q) - (p)) * 6.0 * (2.0 / 3.0 - (tc));                                    /
    }                                                                                            /
    else                                                                                        /
    {                                                                                            /
        (tc) = (p);                                                                                /
    }                                                                                            /
    I_MACRO_END


// h is [0, 360)
// s is [0, 1]
// l is [0, 1]
// r, g, b are [0, 1]
#define HSL2RGB( h, s, l, r, g, b )                                                                /
    I_MACRO_BEGIN                                                                                /
    float _p;                                                                                    /
    float _q;                                                                                    /
    float _hk;                                                                                    /
    float _tr;                                                                                    /
    float _tg;                                                                                    /
    float _tb;                                                                                    /
    assert( (h) < 360 );                                                                        /
    if ( (l) < 0.5 )                                                                            /
    {                                                                                            /
        _q = (l) * (1 + (s));                                                                    /
    }                                                                                            /
    else                                                                                        /
    {                                                                                            /
        _q = (l) + (s) - (l) * (s);                                                                /
    }                                                                                            /
    _p  = 2.0 * (l) - _q;                                                                        /
    _hk = (float) (h) / 360.0;                                                                    /
    _tr = _hk + 1.0 / 3.0;                                                                        /
    if ( _tr < 0 )                                                                                /
        _tr += 1.0;                                                                                /
    else if ( _tr > 1.0 )                                                                        /
        _tr -= 1.0;                                                                                /
    _tg = _hk;                                                                                    /
    if ( _tg < 0 )                                                                                /
        _tg += 1.0;                                                                                /
    else if ( _tg > 1.0 )                                                                        /
        _tg -= 1.0;                                                                                /
    _tb = _hk - 1.0 / 3.0;                                                                        /
    if ( _tb < 0 )                                                                                /
        _tb += 1.0;                                                                                /
    else if ( _tb > 1.0 )                                                                        /
        _tb -= 1.0;                                                                                /
    II_HSL2RGB( _p, _q, _tr );                                                                    /
    II_HSL2RGB( _p, _q, _tg );                                                                    /
    II_HSL2RGB( _p, _q, _tb );                                                                    /
    (r) = _tr;                                                                                    /
    (g) = _tg;                                                                                    /
    (b) = _tb;                                                                                    /
    I_MACRO_END

// r, g, b are [0, 1]
// h is [0, 360)
// s is [0, 1]
// v is [0, 1]
#define RGB2HSV( r, g, b, h, s, v )                                                                /
    I_MACRO_BEGIN                                                                                /
    if ( (r) == (g) && (g) == (b) )                                                                /
    {                                                                                            /
        (h) = 0;                                                                                /
        (s) = 0;                                                                                /
        (v) = (g);                                                                                /
    }                                                                                            /
    else                                                                                        /
    {                                                                                            /
        float _max;                                                                                /
        float _min;                                                                                /
        if ( (r) > (g) )                                                                        /
        {                                                                                        /
            _min = (g) > (b) ? (b) : (g);                                                        /
            if ( (r) > (b) ) /* r is max */                                                        /
            {                                                                                    /
                _max = (r);                                                                        /
                (h)  = ((int) (60.0 * ((g) - (b)) / ((r) - _min) + 0.5) + 360) % 360;            /
            }                                                                                    /
            else /* b is max */                                                                    /
            {                                                                                    /
                _max = (b);                                                                        /
                (h)  = (int) (60.0 * ((r) - (g)) / ((b) - _min) + 0.5) + 240;                    /
            }                                                                                    /
        }                                                                                        /
        else /* (r) <= (g) */                                                                    /
        {                                                                                        /
            _min = (r) > (b) ? (b) : (r);                                                        /
            if ( (g) > (b) ) /* g is max */                                                        /
            {                                                                                    /
                _max = (g);                                                                        /
                (h)  = (int) (60.0 * ((b) - (r)) / ((g) - _min) + 0.5) + 120;                    /
            }                                                                                    /
            else /* b is max */                                                                    /
            {                                                                                    /
                _max = (b);                                                                        /
                (h)  = (int) (60.0 * ((r) - (g)) / ((b) - _min) + 0.5) + 240;                    /
            }                                                                                    /
        }                                                                                        /
        (v) = _max;                                                                                /
        if ( _max == 0 )                                                                        /
        {                                                                                        /
            (s) = 0;                                                                            /
        }                                                                                        /
        else                                                                                    /
        {                                                                                        /
            (s) = (float) (_max - _min) / (float) _max;                                            /
        }                                                                                        /
    }                                                                                            /
    I_MACRO_END

// h is [0, 360)
// s is [0, 1]
// v is [0, 1]
// r, g, b are [0, 255]
#define HSV2RGB( h, s, v, r, g, b )                                                                /
    I_MACRO_BEGIN                                                                                /
    int   _hi;                                                                                    /
    float _f;                                                                                    /
    float _p;                                                                                    /
    float _q;                                                                                    /
    float _t;                                                                                    /
    assert( (h) < 360 );                                                                        /
    _hi = ((int) (h) / 60) % 6;                                                                    /
    _f  = (float) (h) / 60.0 - (int) ((int) (h) / 60);                                            /
    _p  = (v) * (1.0 - (s));                                                                    /
    _q  = (v) * (1.0 - _f * (s));                                                                /
    _t  = (v) * (1.0 - (1.0 - _f) * (s));                                                        /
    switch ( _hi )                                                                                /
    {                                                                                            /
    case 0:                                                                                        /
        (r) = (v);                                                                                /
        (g) = (_t);                                                                                /
        (b) = (_p);                                                                                /
        break;                                                                                    /
    case 1:                                                                                        /
        (r) = (_q);                                                                                /
        (g) = (v);                                                                                /
        (b) = (_p);                                                                                /
        break;                                                                                    /
    case 2:                                                                                        /
        (r) = (_p);                                                                                /
        (g) = (v);                                                                                /
        (b) = (_t);                                                                                /
        break;                                                                                    /
    case 3:                                                                                        /
        (r) = (_p);                                                                                /
        (g) = (_q);                                                                                /
        (b) = (v);                                                                                /
        break;                                                                                    /
    case 4:                                                                                        /
        (r) = (_t);                                                                                /
        (g) = (_p);                                                                                /
        (b) = (v);                                                                                /
        break;                                                                                    /
    case 5:                                                                                        /
        (r) = (v);                                                                                /
        (g) = (_p);                                                                                /
        (b) = (_q);                                                                                /
        break;                                                                                    /
    }                                                                                            /
    I_MACRO_END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值