rgb_to_yuv420.cpp

Andrey Morozov, 2012-10-16 03:58 pm

Download (2 kB)

 
1
inline void rgb_to_yuv(unsigned char   b, unsigned char   g, unsigned char   r,
2
                       unsigned char & y, unsigned char & u, unsigned char & v)
3
{
4
    float yf, uf, vf;
5
6
    //Y = R * 0.299 + G * 0.587 + B * 0.114;
7
    //U = R * -0.169 + G * -0.332 + B * 0.500 + 128.0;
8
    //V = R * 0.500 + G * -0.419 + B * -0.0813 + 128.0;
9
10
    yf =    0.299f * static_cast<float>(r) +
11
            0.587f * static_cast<float>(g) +
12
            0.114f * static_cast<float>(b);
13
    yf = (yf > 255.0f) ? 255.0f: yf;
14
    yf = (yf < 0.0f) ? 0.0f: yf;
15
    y = static_cast<unsigned char>(yf);
16
17
18
    uf =   -0.169f * static_cast<float>(r) -
19
            0.332f * static_cast<float>(g) +
20
            0.500f * static_cast<float>(b) + 128.0;
21
    uf = (uf > 255.0f) ? 255.0f: uf;
22
    uf = (uf < 0.0f) ? 0.0f: uf;
23
    u = static_cast<unsigned char>(uf);
24
25
26
    vf =    0.500f * static_cast<float>(r) -
27
            0.419f * static_cast<float>(g) -
28
            0.081f * static_cast<float>(b) + 128.0;
29
    vf = (vf > 255.0f) ? 255.0f: vf;
30
    vf = (vf < 0.0f) ? 0.0f: vf;
31
    v = static_cast<unsigned char>(vf);
32
33
}
34
35
void RGB_to_YUV420(const unsigned char * rgb, unsigned char * yuv420, int width, int height)
36
{
37
    unsigned char * y_pixel = yuv420;
38
    unsigned char * u_pixel = yuv420 + width * height;
39
    unsigned char * v_pixel = yuv420 + width * height + (width * height / 4);
40
41
    unsigned char * U_tmp = new unsigned char [width * height];
42
    unsigned char * V_tmp = new unsigned char [width * height];
43
44
    int index = 0;
45
    for (int y = 0; y < height; ++y)
46
    {
47
        for (int x = 0; x < width; ++x)
48
        {
49
            rgb_to_yuv(rgb[3 * (y * width + x) + 0], rgb[3 * (y * width + x) + 1], rgb[3 * (y * width + x) + 2], y_pixel[index], U_tmp[index], V_tmp[index]);
50
            index++;
51
        }
52
    }
53
54
    index = 0;
55
    for (int y = 0; y < height; y+=2)
56
    {
57
        for (int x = 0; x < width; x+=2)
58
        {
59
            u_pixel[index] = U_tmp[y * width + x];
60
            v_pixel[index] = V_tmp[y * width + x];
61
            index++;
62
        }
63
    }
64
65
    delete [] U_tmp;
66
    delete [] V_tmp;
67
}