YUV格式学习:YUYV、YVYU、UYVY、VYUY格式转换成RGB
YUYV、YVYU、UYVY、VYUY格式,它们都是YUV422的打包格式——即在内存中,Y、U、V都是挨着排序的。它们的名称就表示了Y、U、V的顺序。像YUYV,就是Y、U、Y、V、Y、U、Y、V。在做转换时,就显得很容易、简单了。
因为极其相近,故在将这几种格式全部封闭到一个函数里做。代码如下:
void yuv422packed_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;unsigned char* p_rgb;p = yuv422p;p_rgb = rgb;init_yuv422p_table();for (i = 0; i < width * height / 2; i++){switch(type){case FMT_YUYV:y = p[0];cb = p[1];cr = p[3];break;case FMT_YVYU:y = p[0];cr = p[1];cb = p[3];break;case FMT_UYVY:cb = p[0];y = p[1];cr = p[2];break;case FMT_VYUY:cr = p[0];y = p[1];cb = p[2];break;default:break;}r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R valueb = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B valueg = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value// 此处可调整RGB排序,BMP图片排序为BGR// 默认排序为:RGBp_rgb[0] = r;p_rgb[1] = g;p_rgb[2] = b;switch(type){case FMT_YUYV:case FMT_YVYU:y = p[2];break;case FMT_UYVY:case FMT_VYUY:y = p[3];break;default:break;}r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000)); //R valueb = MAX (0, MIN (255, (U[cb] + Y1[y])/10000)); //B valueg = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G valuep_rgb[3] = r;p_rgb[4] = g;p_rgb[5] = b;p += 4;p_rgb += 6;}
}
在做转换时,要注意YUV422采样格式,2个Y共用1个U和1个V,因此每一次循环就是读取1个Y、1个U和V转换成R、G、B,再读取下一个Y、U、V。由于UV共用,所以第2次转换时不用再给U、V赋值了。
#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endifstatic long U[256], V[256], Y1[256], Y2[256];typedef enum
{FMT_YUYV=1, FMT_YVYU, FMT_UYVY, FMT_VYUY
}YUV_TYPE;void init_yuv422p_table(void)
{int i;static int init = 0;if (init == 1) return;// Initialize tablefor (i = 0; i < 256; i++){V[i] = 15938 * i - 2221300;U[i] = 20238 * i - 2771300;Y1[i] = 11644 * i;Y2[i] = 19837 * i - 311710;}init = 1;
}
原文链接:https://latelee.blog.csdn.net/article/details/47304581
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
