TV颜色空间—YUV,YIQ,YCbCr

TV颜色空间—YUV,YIQ,YCbCrTV 颜色空间 YUV YIQ YCbCr1 TV 颜色空间 nbsp nbsp nbsp TV 颜色空间广泛应用于电视信号的记录 存储 传输 显示 YUV 和 YIQ 是两种应用于模拟 NTSC 和 PAL 系统的基本颜色编码方式 而 YCbCr 是国际数字电视标准的一部分 上述所有的 TV 颜色空间都有一个共同的特点 把亮度分量 Y 和两个色度分量分隔开来 不是直接对颜色进行编码 2 YUV 颜色空间 nbsp nbsp nbsp YUV 颜色空间是北

TV颜色空间—YUV,YIQ,YCbCr

1.前言


     自然界的颜色千变万化,为了给颜色一个量化的衡量标准,就需要建立色彩空间模型来描述各种各样的颜色,由于人对色彩的感知是一个复杂的生理和心理联合作用的过程,所以在不同的应用领域中为了更好更准确的满足各自的需求,就出现了各种各样的色彩空间模型来量化的描述颜色。我们比较常接触到的就包括 RGB / CMYK / YIQ / YUV / HSI等等。

    对于数字电子多媒体领域来说,我们经常接触到的色彩空间的概念,主要是RGB ,YUV这两种(实际上,这两种体系包含了许多种具体的颜色表达方式和模型,如sRGB, Adobe RGB,YUV422, YUV420 …), RGB是按三基色加光系统的原理来描述颜色,而YUV则是按照 亮度,色差的原理来描述颜色。“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

2.YUV颜色空间的由来

F = r [R] + g [G] + b [B]

3.YUV颜色空间

    YUV颜色空间是北美NTSC和欧洲PAL模拟电视系统颜色编码的基础。亮度分量Y通过下述公式计算出:

TV颜色空间—YUV,YIQ,YCbCr

   上述公式假定的是RGB值是根据TV编码标准进行Gamma校正之后逇值。UV分量是分别对亮度分量与红色分量、亮度分量与蓝色分量进行差值之后再赋予一定的权重:

TV颜色空间—YUV,YIQ,YCbCr

    因此,从RGB转换为YUV的关系为:

TV颜色空间—YUV,YIQ,YCbCr

  相应的,从YUV转换为RGB的关系为:

TV颜色空间—YUV,YIQ,YCbCr

4.YIQ颜色空间

    原始的NTSC系统用了一种YUV的变体进行颜色编码,这种变体称之为YIQ(I for“in-phase”and Qfor “quadrature”)。IQ分量是UV分量进行旋转和镜像之后的数值:

TV颜色空间—YUV,YIQ,YCbCr

  ß=0.576(33度)。Y分量同上述YUV颜色空间计算方式一样。

5.YCbCr颜色空

    YCbCr颜色空间是YUV颜色空间的一种变体,广泛应用于数字电视系统和图像压缩方面(比如JPEG)。色度分量Cb,Cr类似于U,V分量,也是通过亮度值与红色分量和蓝色分量差值之后,在赋予一定的权重计算得出。相比于YUV颜色空间,在RGB转换为YUV颜色空间的时候,其各个分量的权重值稍有不同。如下公式:

TV颜色空间—YUV,YIQ,YCbCr

  相应的从YCbCr转换为RGB颜色空间为:

TV颜色空间—YUV,YIQ,YCbCr


   BT.601中规定WR= 0.299,Wb=0.144,WG = 0.587,因此,上述公式变换为:

TV颜色空间—YUV,YIQ,YCbCr

   YCbCr转换为RGB公式为:

TV颜色空间—YUV,YIQ,YCbCr

    由于上述U,VI,Q,Cb,Cr可能为负数或正数,为了图像能够显示这些分量的负值,一般会在上述分量计算公式之后加上一个偏移量,使得其颜色分量为正值。比如,对于8bit表示一个分量的像素而言,其颜色分量的偏移量一般设置为128=2的7次方。

6.关键代码:

int RGB2YUV(IMAGE_TYPE *bmp_img, DWORD width, DWORD height,TYPE_YUV type) { T_U32 lineByte,Source_linebyte,source_index,dst_index; T_U16 i,j; T_U16 k = 0; T_U8 *Bmp8_img,*Source_img,R,G,B,*Y_img,*U_img,*V_img; int newbiBitCount =8,Y,U,V,I,Q,Cb,Cr; int colorTablesize; RGBQUAD colortable[256]; RGBQUAD *pColorTable1 = colortable; BITMAPFILEHEADER bf; BITMAPINFOHEADER bi; FILE *BMP2Y_fp = fopen("BMP2Y.bmp","wb"); FILE *BMP2U_fp = fopen("BMP2U.bmp","wb"); FILE *BMP2V_fp = fopen("BMP2V.bmp","wb"); if(NULL == BMP2Y_fp) { printf("Can't open BMP2Y.bmp\n"); return -1; } if(NULL == BMP2U_fp) { printf("Can't open BMP2U.bmp\n"); return -1; } if(NULL == BMP2V_fp) { printf("Can't open BMP2V.bmp\n"); return -1; } memset(&bf, 0, sizeof(bf)); memset(&bi, 0, sizeof(bi)); bf.bfType = (WORD)0x4d42; //8位图像数据每行字节数为4的倍数 lineByte = (width * newbiBitCount / 8 + 3) / 4 * 4; colorTablesize = 1024; bf.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize+lineByte*height;//图像数据加上调色板信息和前两部分BMP文件信息 bf.bfReserved1 = 0; bf.bfReserved2 = 0; bf.bfOffbits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize;//注意此offset是BMP前三部分数据,也就是真正图像数据的前面几部分之和 bi.biSize = 40; bi.biHeight = height; bi.biWidth = width; bi.biPlanes = 1; bi.biCompression = 0; bi.biBitCount = newbiBitCount;//每一个像素由8 bits表示 bi.biSizeImage = lineByte*height; bi.biXPelsPerMeter = 0; bi.biYPelsPerMter = 0; bi.biClrImportant = 0; bi.biClrUsed = 0; Source_linebyte = WIDTHBYTES(width*24); Source_img = bmp_img+54; for (i = 0; i<256; ++i) { colortable[i].rgbBlue = i; colortable[i].rgbGreen = i; colortable[i].rgbRed = i; colortable[i].rgbReserved = 0; } fwrite(&bf,sizeof(BITMAPFILEHEADER),1,BMP2Y_fp); fwrite(&bi,sizeof(BITMAPINFOHEADER),1,BMP2Y_fp); fwrite(pColorTable1, sizeof(RGBQUAD), 256, BMP2Y_fp); fwrite(&bf,sizeof(BITMAPFILEHEADER),1,BMP2U_fp); fwrite(&bi,sizeof(BITMAPINFOHEADER),1,BMP2U_fp); fwrite(pColorTable1, sizeof(RGBQUAD), 256, BMP2U_fp); fwrite(&bf,sizeof(BITMAPFILEHEADER),1,BMP2V_fp); fwrite(&bi,sizeof(BITMAPINFOHEADER),1,BMP2V_fp); fwrite(pColorTable1, sizeof(RGBQUAD), 256, BMP2V_fp); Source_img = bmp_img+54; Y_img = (T_U8*)malloc(width*height); U_img = (T_U8*)malloc(width*height); V_img = (T_U8*)malloc(width*height); if(NULL == Y_img || NULL == U_img || NULL == V_img) { printf("Can't malloc YUV_img\n"); return -1; } switch (type) { case YUV: { for (i = 0; i < height;i++) { for (j = 0;j < width;j++) { source_index = Source_linebyte*i+3*j; dst_index = lineByte*i+j; R = Source_img[source_index+2]; G = Source_img[source_index+1]; B = Source_img[source_index]; #if 0 Y = 0.299*R+0.548*G+0.114*B; U = -0.147*R-0.289*G+0.436*B+128; V = 0.615*R-0.515*G-0.100*B+128; #endif Y = (306*R+561*G+117)>>10; U = (-150*R-296*G+446*B+)>>10; V = (630*R-527*G-102*G+)>>10; Y_img[dst_index] = (T_U8)Y; U_img[dst_index] = (T_U8)U; V_img[dst_index] = (T_U8)V; } } } case YIQ: { for (i = 0; i < height;i++) { for (j = 0;j < width;j++) { source_index = Source_linebyte*i+3*j; dst_index = lineByte*i+j; R = Source_img[source_index+2]; G = Source_img[source_index+1]; B = Source_img[source_index]; #if 1 Y = 0.299*R+0.548*G+0.114*B; U = -0.147*R-0.289*G+0.436*B; V = 0.615*R-0.515*G-0.100*B; #endif #if 0 Y = (306*R+561*G+117)>>10; U = (-150*R-296*G+446*B+)>>10; V = (630*R-527*G-102*G+)>>10; #endif I =(int) (-sin(0.576)*U+V*cos(0.576))+128; Q = (int)(U*cos(0.576)+V*sin(0.576))+128; Y_img[dst_index] = (T_U8)Y; U_img[dst_index] = (T_U8)I; V_img[dst_index] = (T_U8)Q; } } } case YCBCR: { for (i = 0; i < height;i++) { for (j = 0;j < width;j++) { source_index = Source_linebyte*i+3*j; dst_index = lineByte*i+j; R = Source_img[source_index+2]; G = Source_img[source_index+1]; B = Source_img[source_index]; #if 1 Y = 0.299*R+0.587*G+0.114*B; Cb = -0.169*R-0.331*G+0.5*B+128; Cr = 0.5*R-0.419*G-0.081*B+128; #endif #if 0 Y = (306*R+601*G+117)>>10; Cb = (-173*R-339*G+512*B+)>>10; Cr = (512*R-429*G-83*G+)>>10; #endif Y_img[dst_index] = (T_U8)Y; U_img[dst_index] = (T_U8)Cb; V_img[dst_index] = (T_U8)Cr; } } } break; } fwrite(Y_img, lineByte*height, 1, BMP2Y_fp); fwrite(U_img, lineByte*height, 1, BMP2U_fp); fwrite(V_img, lineByte*height, 1, BMP2V_fp); fclose(BMP2Y_fp); fclose(BMP2U_fp); fclose(BMP2V_fp); free(Y_img); free(U_img); free(V_img); return 0; } 

7.图像效果

TV颜色空间—YUV,YIQ,YCbCr

TV颜色空间—YUV,YIQ,YCbCr TV颜色空间—YUV,YIQ,YCbCr TV颜色空间—YUV,YIQ,YCbCr

YUV颜色空间的Y、U、V分量

TV颜色空间—YUV,YIQ,YCbCrTV颜色空间—YUV,YIQ,YCbCrTV颜色空间—YUV,YIQ,YCbCr


YIQ颜色空间的Y、I、Q分量
TV颜色空间—YUV,YIQ,YCbCr TV颜色空间—YUV,YIQ,YCbCr TV颜色空间—YUV,YIQ,YCbCr




















版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/210719.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午7:02
下一篇 2026年3月19日 上午7:03


相关推荐

  • 基于ARM Cortex-M和Eclipse的SWO单总线输出

    基于ARM Cortex-M和Eclipse的SWO单总线输出nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 最近在 MCUonEclipse 网站上看到 ErichStyger 所写的一篇有关通过 SWD 的跟踪接口 SWO 获取 ARMCortex M 相关信息的文章 文章结构明晰 讲解透彻 本人深受启发 特意将其翻译过来供各位同仁参考 当然限于个人水平 有不当之处恳请指正 原文网址 https mcuoneclipse com 2016 10 17 tutorial using single

    2026年3月20日
    2
  • webpack图片压缩_webpack怎么引入图片

    webpack图片压缩_webpack怎么引入图片图片处理url-loader(webpack5之前的处理方式)在项目开发中,我们时长会需要使用到图片,比如在img文件夹中有图片test1.png,然后在normal.css中会引用到图片body

    2022年7月31日
    9
  • LitJson写入中文乱码问题

    LitJson写入中文乱码问题今天用 LitJson 写入数据出现乱码问题 原因是 LitJson 在写入的时候进行了转义字符 只支持 unicode 编码 所以出现了乱码 又因为 LitJson dll 无法修改低层 用 Regex Unescape 取消转义字符就 OK 了 1 未修改出现的结果 打印出来就是一堆转义后的字符串了 2 修改后的结果 这样在写入文本就没有问题了

    2026年1月28日
    1
  • 昆山桶装水配送电话_桶装水订购

    昆山桶装水配送电话_桶装水订购昆山桶装水:农夫山泉19元千岛湖山泉15元洞庭山12元憔依(生态)14元憔依(矿化)11元憔依(纯水)10元水森活10元虎丘8元亭林泉8元泰富7元最好的服务,只为你能满意。服务电话

    2022年8月5日
    11
  • 【kubernetes集群系列(一)】Master安装(使用kubeadm)

    【kubernetes集群系列(一)】Master安装(使用kubeadm)

    2021年5月13日
    125
  • 计算机ata考试试题答案,计算机ATA考试(高级)第一套试卷

    计算机ata考试试题答案,计算机ATA考试(高级)第一套试卷计算机ATA考试(高级)第一套试题一、启动资源管理器二、在C盘的根目录下新建文件夹,文件名为“4000001”三、将C盘下“KSML2”文件夹内的文件KS1-7.DOC、KS2-5.DOC、KS3-14.DOC、KS4-20.XLS、KS5-8.XLS、KS6-6.ppt、KS7-18.XLS、KS8-4.PST一次性复制到C盘下4000001文件夹中,并分别重命名为A1.DOC、A2.DOC、A…

    2022年7月13日
    27

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号