C语言实现YUV_NV12转换成RGB
一 、YUV2RGB的公式
R = Y + 1.4075 *(V-128)
G = Y – 0.3455 *(U –128) – 0.7169 *(V –128)
B = Y + 1.779 *(U – 128)
二 、RGB2YUV的公式
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
三 、NV12的格式
YUV_NV12属于YUV420格式,四个Y对应一对UV(如Y00、Y01、Y10、Y11对应U0和V0),通常一幅height * width * 3的RGB图对应height * width * 3 / 2 的YUV数据(即Y00、Y01、Y10、Y11对应相应位置的RGB各值),NV12的具体编码可参照下图所示(若将下图U、V顺序进行颠倒即为YUV_NV21格式):
四 、转换核心代码
/*参数含义*********************
pYUvBuf: YUV裸数据
pRgbBuf: RGB裸数据
height: 图像高度
width: 图像宽度
**************************/
int yuv2rgb_nv12(unsigned char* pYuvBuf, unsigned char* pRgbBuf, int height, int width)
{
if(width < 1 || height < 1 || pYuvBuf == NULL || pRgbBuf == NULL)
{
return 0;
}
const long len = height * width;
// Y与UV数据地址
unsigned char *yData = pYuvBuf;
unsigned char *uvData = yData + len;
// R、G、B数据地址
unsigned char *rData = pRgbBuf;
unsigned char *gData = rData + len;
unsigned char *bData = gData + len;
int R[4], G[4], B[4];
int Y[4], U, V;
int y0_Idx, y1_Idx, uIdx, vIdx;
for (int i = 0; i < height; i=i+2)
{
for (int j = 0; j < width; j=j+2)
{
y0_Idx = i * width + j;
y1_Idx = (i + 1) * width + j;
// Y[0]、Y[1]、Y[2]、Y[3]分别代表 Y00、Y01、Y10、Y11
Y[0] = yData[y0_Idx];
Y[1] = yData[y0_Idx + 1];
Y[2] = yData[y1_Idx];
Y[3] = yData[y1_Idx + 1];
uIdx = (i / 2) * width + j;
vIdx = uIdx + 1;
U = uvData[uIdx];
V = uvData[vIdx];
R[0] = Y[0] + 1.402 * (V - 128);
G[0] = Y[0] - 0.34414 * (U - 128) + 0.71414 * (V - 128);
B[0] = Y[0] + 1.772 * (U - 128);
R[1] = Y[1] + 1.402 * (V - 128);
G[1] = Y[1] - 0.34414 * (U - 128) + 0.71414 * (V - 128);
B[1] = Y[1] + 1.772 * (U - 128);
R[2] = Y[2] + 1.402 * (V - 128);
G[2] = Y[2] - 0.34414 * (U - 128) + 0.71414 * (V - 128);
B[2] = Y[2] + 1.772 * (U - 128);
R[3] = Y[3] + 1.402 * (V - 128);
G[3] = Y[3] - 0.34414 * (U - 128) + 0.71414 * (V - 128);
B[3] = Y[3] + 1.772 * (U - 128);
// 像素值限定在 0-255
for (int k = 0; k < 4; ++k)
{
if(R[k] >= 0 && R[k] <= 255)
{
R[k] = R[k];
}
else
{
R[k] = (R[K] < 0) ? 0 : 255;
}
if(G[k] >= 0 && G[k] <= 255)
{
G[k] = G[k];
}
else
{
G[k] = (G[K] < 0) ? 0 : 255;
}
if(B[k] >= 0 && B[k] <= 255)
{
B[k] = B[k];
}
else
{
B[k] = (B[K] < 0) ? 0 : 255;
}
}
*(rData + y0_Idx) = R[0];
*(gData + y0_Idx) = G[0];
*(bData + y0_Idx) = B[0];
*(rData + y0_Idx + 1) = R[1];
*(gData + y0_Idx + 1) = G[1];
*(bData + y0_Idx + 1) = B[1];
*(rData + y1_Idx) = R[2];
*(gData + y1_Idx) = G[2];
*(bData + y1_Idx) = B[2];
*(rData + y1_Idx + 1) = R[3];
*(gData + y1_Idx + 1) = G[3];
*(bData + y1_Idx + 1) = B[3];
}
}
return 1;
}
转载需标明地址:https://blog.csdn.net/weixin_39444746/article/details/90417137