YUV422P、YV16、NV16、NV61格式转换成RGB24
2017-01-20 15:34
453 查看
YUV422有打包格式(Packed),一如前文所述。同时还有平面格式(Planar),即Y、U、V是分开存储的,每个分量占一块地方,其中Y为width*height,而U、V合占width*height,该种格式每个像素占16比特。根据U、V的顺序,分出2种格式,U前V后即YUV422P,也叫I422,V前U后,叫YV16(YV表示Y后面跟着V,16表示16bit)。另外,还有一种变态的半平面格式(Semi-planar),即Y单独占一块地方,但其后U、V又紧挨着排在一起,根据U、V的顺序,又有2种,U前V后叫NV16,在国内好像很多人叫它为YUV422SP格式;V前U后叫NV61。不过这种格式似乎不太受VLC欢迎(具体可去看看VLC的wiki)。
先给出YUV422平面格式的转换函数,如下:
[cpp] view
plain copy
/**
内存分布
w
+--------------------+
|Y0Y1Y2Y3... |
|... | h
|... |
| |
+--------------------+
|U0U1 |
|... | h
|... |
| |
+----------+
|V0V1 |
|... | h
|... |
| |
+----------+
w/2
*/
void yuv422p_to_rgb24(YUV_TYPE type, unsigned char* yuv422p, unsigned char* rgb, int width, int height)
{
int y, cb, cr;
int r, g, b;
int i = 0;
unsigned char* p_y;
unsigned char* p_u;
unsigned char* p_v;
unsigned char* p_rgb;
p_y = yuv422p;
p_u = p_y + width * height;
p_v = p_u + width * height / 2;
if (type == FMT_YV16)
{
p_v = p_y + width * height;
p_u = p_u + width * height / 2;
}
p_rgb = rgb;
init_yuv422p_table();
for (i = 0; i < width * height / 2; i++)
{
y = p_y[0];
cb = p_u[0];
cr = p_v[0];
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
// 此处可调整RGB排序,BMP图片排序为BGR
// 默认排序为:RGB
p_rgb[0] = r;
p_rgb[1] = g;
p_rgb[2] = b;
y = p_y[1];
cb = p_u[0];
cr = p_v[0];
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
p_rgb[3] = r;
p_rgb[4] = g;
p_rgb[5] = b;
p_y += 2;
p_u += 1;
p_v += 1;
p_rgb += 6;
}
}
接着给出NV16、NV61转换成RGB的函数,如下:
[cpp] view
plain copy
/**
内存分布
w
+--------------------+
|Y0Y1Y2Y3... |
|... | h
|... |
| |
+--------------------+
|U0V0U1V1 |
|... | h
|... |
| |
+--------------------+
w/2
UV交织为NV16,VU交织为NV61
可以与上一函数合并,但方便查看,还是不合并
*/
void yuv422sp_to_rgb24(YUV_TYPE type, unsigned char* yuv422sp, unsigned char* rgb, int width, int height)
{
int y, cb, cr;
int r, g, b;
int i = 0;
unsigned char* p_y;
unsigned char* p_uv;
unsigned char* p_rgb;
p_y = yuv422sp;
p_uv = p_y + width * height; // uv分量在Y后面
p_rgb = rgb;
init_yuv422p_table();
for (i = 0; i < width * height / 2; i++)
{
y = p_y[0];
if (type == FMT_NV16)
{
cb = p_uv[0];
cr = p_uv[1]; // v紧跟u,在u的下一个位置
}
if (type == FMT_NV61)
{
cr = p_uv[0];
cb = p_uv[1]; // u紧跟v,在v的下一个位置
}
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
// 此处可调整RGB排序,BMP图片排序为BGR
// 默认排序为:RGB
p_rgb[0] = r;
p_rgb[1] = g;
p_rgb[2] = b;
y = p_y[1];
if (type == FMT_NV16)
{
cb = p_uv[0];
cr = p_uv[1];
}
if (type == FMT_NV61)
{
cr = p_uv[0];
cb = p_uv[1];
}
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
p_rgb[3] = r;
p_rgb[4] = g;
p_rgb[5] = b;
p_y += 2;
p_uv += 2;
p_rgb += 6;
}
}
参考资料:
http://www.fourcc.org/yuv.php
https://wiki.videolan.org/YUV/
先给出YUV422平面格式的转换函数,如下:
[cpp] view
plain copy
/**
内存分布
w
+--------------------+
|Y0Y1Y2Y3... |
|... | h
|... |
| |
+--------------------+
|U0U1 |
|... | h
|... |
| |
+----------+
|V0V1 |
|... | h
|... |
| |
+----------+
w/2
*/
void yuv422p_to_rgb24(YUV_TYPE type, unsigned char* yuv422p, unsigned char* rgb, int width, int height)
{
int y, cb, cr;
int r, g, b;
int i = 0;
unsigned char* p_y;
unsigned char* p_u;
unsigned char* p_v;
unsigned char* p_rgb;
p_y = yuv422p;
p_u = p_y + width * height;
p_v = p_u + width * height / 2;
if (type == FMT_YV16)
{
p_v = p_y + width * height;
p_u = p_u + width * height / 2;
}
p_rgb = rgb;
init_yuv422p_table();
for (i = 0; i < width * height / 2; i++)
{
y = p_y[0];
cb = p_u[0];
cr = p_v[0];
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
// 此处可调整RGB排序,BMP图片排序为BGR
// 默认排序为:RGB
p_rgb[0] = r;
p_rgb[1] = g;
p_rgb[2] = b;
y = p_y[1];
cb = p_u[0];
cr = p_v[0];
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
p_rgb[3] = r;
p_rgb[4] = g;
p_rgb[5] = b;
p_y += 2;
p_u += 1;
p_v += 1;
p_rgb += 6;
}
}
接着给出NV16、NV61转换成RGB的函数,如下:
[cpp] view
plain copy
/**
内存分布
w
+--------------------+
|Y0Y1Y2Y3... |
|... | h
|... |
| |
+--------------------+
|U0V0U1V1 |
|... | h
|... |
| |
+--------------------+
w/2
UV交织为NV16,VU交织为NV61
可以与上一函数合并,但方便查看,还是不合并
*/
void yuv422sp_to_rgb24(YUV_TYPE type, unsigned char* yuv422sp, unsigned char* rgb, int width, int height)
{
int y, cb, cr;
int r, g, b;
int i = 0;
unsigned char* p_y;
unsigned char* p_uv;
unsigned char* p_rgb;
p_y = yuv422sp;
p_uv = p_y + width * height; // uv分量在Y后面
p_rgb = rgb;
init_yuv422p_table();
for (i = 0; i < width * height / 2; i++)
{
y = p_y[0];
if (type == FMT_NV16)
{
cb = p_uv[0];
cr = p_uv[1]; // v紧跟u,在u的下一个位置
}
if (type == FMT_NV61)
{
cr = p_uv[0];
cb = p_uv[1]; // u紧跟v,在v的下一个位置
}
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
// 此处可调整RGB排序,BMP图片排序为BGR
// 默认排序为:RGB
p_rgb[0] = r;
p_rgb[1] = g;
p_rgb[2] = b;
y = p_y[1];
if (type == FMT_NV16)
{
cb = p_uv[0];
cr = p_uv[1];
}
if (type == FMT_NV61)
{
cr = p_uv[0];
cb = p_uv[1];
}
r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R value
b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B value
g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
p_rgb[3] = r;
p_rgb[4] = g;
p_rgb[5] = b;
p_y += 2;
p_uv += 2;
p_rgb += 6;
}
}
参考资料:
http://www.fourcc.org/yuv.php
https://wiki.videolan.org/YUV/
相关文章推荐
- YUV格式学习:YUV422P、YV16、NV16、NV61格式转换成RGB24
- YUV格式学习:YUV420P、YV12、NV12、NV21格式转换成RGB24(转载)
- YUV422格式的数据转换成RGB24
- YUV格式学习:YUV420P、YV12、NV12、NV21格式转换成RGB24
- YUV格式学习:YUV420P、YV12、NV12、NV21格式转换成RGB24
- YUV格式学习:Y转换成RGB24
- YUV格式学习:YUV444转换RGB24
- YUV格式学习:YUYV、YVYU、UYVY、VYUY格式转换成RGB24
- YV12 格式的图片转换为 RGB24 格式
- RGB16转换RGB24
- YUYV格式到RGB格式的转换
- RGB与YUV图像视频格式的相互转换(转)
- 十六进制颜色值域RGB格式颜色值之间的相互转换
- 转:查表法转换YV12到RGB24的例子(附代码)
- YUV422P(UYVY)转换到RGB , 基于Opencv2.4.10
- RGB与YUV图像视频格式的相互转换
- S3C6410 FramBuffer编程(四) --- RGB565、RGB24简介,以及RGB565转换为RGB24
- YUY2(YUV) 与 RGB 格式图片的相互转换 以及 基于YUY2(YUV)的blending
- YUV格式学习:NV16和YUV422P格式互换
- YUY2(YUV) 与 RGB 格式图片的相互转换 以及 基于YUY2(YUV)的blending