C++ 实现YUV和RGB图像数据互转

1、RGB转换为YUV

可以使用以下公式进行转换:

Y = 0.299 * R + 0.587 * G + 0.114 * B

U = -0.14713 * R - 0.28886 * G + 0.436 * B

V = 0.615 * R - 0.51498 * G - 0.10001 * B

其中,R、G和B分别代表红色、绿色和蓝色分量。这些公式适用于标准的YUV格式,如YUV420、YUV422等。

以下是一个简单的示例代码,演示了如何将RGB图像数据转换为YUV格式:

void ConvertRGBtoYUV(unsigned char* rgbData, unsigned char* yuvData, int width, int height)
{
    int imageSize = width * height;
    int uvSize = imageSize / 4;

    unsigned char* yData = yuvData;
    unsigned char* uData = yuvData + imageSize;
    unsigned char* vData = yuvData + imageSize + uvSize;

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int index = i * width + j;
            int rgbIndex = index * 3;

            unsigned char r = rgbData[rgbIndex];
            unsigned char g = rgbData[rgbIndex + 1];
            unsigned char b = rgbData[rgbIndex + 2];

            int y = 0.299 * r + 0.587 * g + 0.114 * b;
            int u = -0.14713 * r - 0.28886 * g + 0.436 * b;
            int v = 0.615 * r - 0.51498 * g - 0.10001 * b;

            y = (y < 0) ? 0 : ((y > 255) ? 255 : y);
            u = (u < 0) ? 0 : ((u > 255) ? 255 : u);
            v = (v < 0) ? 0 : ((v > 255) ? 255 : v);

            int yuvIndex = index;
            yData[yuvIndex] = y;
            if (i % 2 == 0 && j % 2 == 0)
            {
                int uvIndex = (i / 2) * (width / 2) + (j / 2);
                uData[uvIndex] = u;
                vData[uvIndex] = v;
            }
        }
    }
}

2、YUV转换为RGB

可以使用以下公式进行转换:

R = Y + 1.402 * (Cr - 128)

G = Y - 0.344136 * (Cb - 128) - 0.714136 * (Cr - 128)

B = Y + 1.772 * (Cb - 128)

其中,Y代表亮度分量,Cb和Cr代表色度分量。这些公式适用于标准的YUV格式,如YUV420、YUV422等。

以下是一个简单的示例代码,演示了如何将YUV图像数据转换为RGB格式: 

void ConvertYUVtoRGB(unsigned char* yuvData, unsigned char* rgbData, int width, int height)
{
    int imageSize = width * height;
    int uvSize = imageSize / 4;

    unsigned char* yData = yuvData;
    unsigned char* uData = yuvData + imageSize;
    unsigned char* vData = yuvData + imageSize + uvSize;

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            int index = i * width + j;
            int uvIndex = (i / 2) * (width / 2) + (j / 2);

            unsigned char y = yData[index];
            unsigned char u = uData[uvIndex];
            unsigned char v = vData[uvIndex];

            int r = y + 1.402 * (v - 128);
            int g = y - 0.344136 * (u - 128) - 0.714136 * (v - 128);
            int b = y + 1.772 * (u - 128);

            r = (r < 0) ? 0 : ((r > 255) ? 255 : r);
            g = (g < 0) ? 0 : ((g > 255) ? 255 : g);
            b = (b < 0) ? 0 : ((b > 255) ? 255 : b);

            int rgbIndex = index * 3;
            rgbData[rgbIndex] = r;
            rgbData[rgbIndex + 1] = g;
            rgbData[rgbIndex + 2] = b;
        }
    }
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值