Y=+0.299R+0.587G+0.114B
U0=0.564(B-Y)=−0.1684R−0.3316G+0.5B
V0=0.713(R-Y)=+0.5R−0.4187G−0.0813B

所以
B-Y=U0/0.564 B=Y+1.773U0
R-Y=V0/0.713 R=Y+1.403V0
G=(Y-(0.299R+0.114B))/0.587 G=Y-0.714V0-0.344U0

U=U0+128
V=V0+128

所以
B=Y+1.773U-226.944
R=Y+1.403V-179.584
G=Y-0.714V-0.344U+135.424

yuv2rgb.cpp:

#include "stdlib.h"
#include "yuv2rgb.h"
#include <stdio.h>static float R_V01403[256],B_U01773[256], G_U_0344[256],G_V_0714[256];int YUV2RGB(int x_dim, int y_dim, void* bmp, void* rgb_out)
{static int init_done = 0;long i, j, size;unsigned char* y, * u, * v;unsigned char* r, * g, * b;size = x_dim * y_dim;if (init_done == 0){InitLookupTable();init_done = 1;}// allocate memoryy = (unsigned char*)bmp;b = (unsigned char*)rgb_out;// convert RGB to YUVfor (j = 0; j < y_dim; j++){for (i = 0; i < x_dim; i++) {g = b + 1;r = b + 2;u = y + x_dim * y_dim - (i + 1) / 2 - (j + 1)/2 * x_dim/2;v = y + x_dim * y_dim + x_dim / 2 * y_dim / 2 - (i + 1) / 2 - (j + 1)/2  * x_dim/2;int rr, gg, bb;rr= (int)(*y + R_V01403[*v]); //-179.584gg=(int)(*y + G_U_0344[*u] + G_V_0714[*v]);//+ 135.424bb=(int)(*y + B_U01773[*u]);//- 226.944*r = rr;//(unsigned char)(*y + R_V01403[*v] ); //-179.584*g = gg;// (unsigned char)(*y + G_U_0344[*u] + G_V_0714[*v]);//+ 135.424*b = bb;//(unsigned char)(*y + B_U01773[*u] );//- 226.944y++;b+=3;}}return 0;
}void InitLookupTable()
{int i;for (i = 0; i < 256; i++) R_V01403[i] = (float)1.403 * (i-128);for (i = 0; i < 256; i++) B_U01773[i] = (float)1.773 * (i-128);for (i = 0; i < 256; i++) G_U_0344[i] = (float)-0.344 * (i-128);for (i = 0; i < 256; i++) G_V_0714[i] = (float)-0.714 * (i-128);
}

main.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "yuv2rgb.h"
#pragma warning(disable:4996)
#define u_int8_t    unsigned __int8
#define u_int       unsigned __int32
#define u_int32_t   unsigned __int32
#define FALSE       false
#define TRUE        trueint main(int argc, char** argv)
{/* variables controlable from command line */u_int frameWidth = 352;          /* --width=<uint> */u_int frameHeight = 240;        /* --height=<uint> */bool flip = TRUE;              /* --flip */unsigned int i;/* internal variables */char* rgbFileName = NULL;char* yuvFileName = NULL;FILE* rgbFile = NULL;FILE* yuvFile = NULL;u_int8_t* yuvBuf = NULL;u_int8_t* rgbBuf = NULL;u_int32_t videoFramesWritten = 0;/* begin process command line *//* point to the specified file names */yuvFileName = argv[1];rgbFileName = argv[2];frameWidth = atoi(argv[3]);frameHeight = atoi(argv[4]);/* open the RGB file */yuvFile = fopen(yuvFileName, "rb");if (yuvFile == NULL){printf("cannot find yuv file\n");exit(1);}else{printf("The input yuv file is %s\n", yuvFileName);}/* open the RAW file */rgbFile = fopen(rgbFileName, "wb");if (rgbFile == NULL){printf("cannot find rgb file\n");exit(1);}else{printf("The output rgb file is %s\n", rgbFileName);}/* get an input buffer for a frame */yuvBuf = (u_int8_t*)malloc(frameWidth * frameHeight * 1.5);/* get the output buffers for a frame */rgbBuf = (u_int8_t*)malloc(frameWidth * frameHeight*3);if (yuvBuf == NULL || rgbBuf == NULL){printf("no enough memory\n");exit(1);}while (fread(yuvBuf, 1, frameWidth * frameHeight * 1.5, yuvFile)){if (YUV2RGB(frameWidth, frameHeight, yuvBuf, rgbBuf)){printf("error");return 0;}for (i = 0; i < frameWidth * frameHeight*3; i++){if (rgbBuf[i] < 0) rgbBuf[i] = 0;if (rgbBuf[i] > 255) rgbBuf[i] = 255;}
/*for (i = 0; i < frameWidth * frameHeight / 4; i++){if (uBuf[i] < 16) uBuf[i] = 16;if (uBuf[i] > 240) uBuf[i] = 240;if (vBuf[i] < 16) vBuf[i] = 16;if (vBuf[i] > 240) vBuf[i] = 240;}fwrite(bBuf, 1, frameWidth * frameHeight, yuvFile);fwrite(gBuf, 1, (frameWidth * frameHeight) / 4, yuvFile);fwrite(rBuf, 1, (frameWidth * frameHeight) / 4, yuvFile);*/fwrite(rgbBuf, 1, frameWidth*frameHeight*3, rgbFile);printf("\r...%d", ++videoFramesWritten);}printf("\n%u %ux%u video frames written\n",videoFramesWritten, frameWidth, frameHeight);/* cleanup */fclose(rgbFile);fclose(yuvFile);return(0);
}

yuv2rgb.h

#pragma once
int YUV2RGB(int x_dim, int y_dim, void* bmp, void* rgb_out);void InitLookupTable();

图片出现以下错误:

观察正确的yuv与rgb大小和获得的yuv与rgb大小:

正确值:

获得值:

​对比可知获得的u、v值异常偏小,导致rgb图像错误。
检验得偏移量错误。

改正偏移量部分:

     for (j = 0; j < y_dim; j++){for (i = 0; i < x_dim; i++) {g = b + 1;r = b + 2;u = y + x_dim * y_dim - (i + 1) / 2 - j * 2 * x_dim / 2 + (j + 1) / 2 * x_dim / 2;v = y + x_dim * y_dim + x_dim / 2 * y_dim / 2 - (i + 1) / 2 - j * 2 * x_dim / 2 + (j + 1) / 2 * x_dim / 2;int rr, gg, bb;rr= (int)(*y + R_V01403[*v]); gg=(int)(*y + G_U_0344[*u] + G_V_0714[*v]);bb=(int)(*y + B_U01773[*u]);*r=rr;*g=gg;*b=bb;y++;b+=3;}}

改正后结果:

有部分像素值越界。

将值限定在0~255:

             rr= (int)(*y + R_V01403[*v]); //-179.584gg=(int)(*y + G_U_0344[*u] + G_V_0714[*v]);//+ 135.424bb=(int)(*y + B_U01773[*u]);//- 226.944if (rr < 0) rr = 0;if (rr > 255) rr = 255;if (gg < 0) gg = 0;if (gg > 255) gg = 255;if (bb < 0) bb = 0;if (bb > 255) bb = 255;*r = rr;*g = gg;*b = bb;

改正后图像:

变换前yuv图像:

该yuv文件为4:2:0格式,u与v的数量为y的1/4,由总数1/4的u与v生成r、g、b会带来一定误差,同时进行转换计算时由小数变为整数也会产生一定误差,但只观察图像时难以辨别。

编写彩色空间转换程序:YUVtoRGB相关推荐

  1. 实验一:彩色空间转换(YUV2RGB)

    实验一:彩色空间转换 #ifndef/#define/#endif 使用详解:http://blog.csdn.net/abc5382334/article/details/18052757 Debu ...

  2. 实验一 |彩色空间rgb和yuv的相互转换

    彩色空间转换 一.实验目的 1.基本要求:编写RGB转化为YUV程序,重点掌握函数定义,部分查找表的初 始化和调用,缓冲区分配.将得到的RGB文件转换为YUV文件,用YUV Viewer播放器观 看, ...

  3. 图像处理(1)--数字图像及彩色空间

    文章结构 1. 数字图像 2. 彩色空间 2.1 RGB 2.2 CMY和CMYK 2.3 HSI 2.4 YIQ 2.5 YUV 2.6 YCbCr 3. 伪彩色图像处理 4. 全彩色图像处理 5. ...

  4. 基于OpenCV的彩色空间互转

    Datawhale干货 作者:姚童,Datawhale优秀学习者 图像彩色空间互转在图像处理中应用非常广泛,而且很多算法只对灰度图有效:另外,相比RGB,其他颜色空间(比如HSV.HSI)更具可分离性 ...

  5. 彩色空间及cvtColor解析

    首先,我们要了解:什么是彩色空间呢? 许多人都知道在绘画时可以使用红色.黄色和蓝色这三种原色生成不同的颜色,这些颜色就定义了一个色彩空间.我们将品红色的量定义为X 坐标轴.青色的量定义为Y坐标轴.黄色 ...

  6. 第6章 Python 数字图像处理(DIP) - 彩色图像处理3 -色彩变换、彩色校正、彩色图像平滑和锐化、HSI彩色空间中的分割、RGB空间中的分割、彩色边缘检测

    这里写目录标题 色彩变换 彩色图像平滑和锐化 使用彩色分割图像 HSI 彩色空间中的分割 RGB空间中的分割 彩色边缘检测 彩色图像中的噪声 色彩变换 # 图像颜色分量的显示 from PIL imp ...

  7. 计算机视觉基础——图像处理(彩色空间互转)cpp+python

    3.1 简介 图像彩色空间互转在图像处理中应用非常广泛,而且很多算法只对灰度图有效:另外,相比RGB,其他颜色空间(比如HSV.HSI)更具可分离性和可操作性,所以很多图像算法需要将图像从RGB转为其 ...

  8. 【学习 OpenCV】—— 将一个3通道的像素点转换到新的彩色空间

    将一个3通道的像素点,cv::Vec<uchar, 3> target,转换到新的彩色空间,比如 Lab 彩色空间. 因为封装好的 api cv::cvtColor() 处理的对象是 cv ...

  9. 彩色空间(Color Space)

    背景 学习openCV-Python Tutorial,在Image Processing in OpenCV这一节里有提到彩色空间的转换,结合其他的一些资料对彩色空间(Color Space),彩色 ...

最新文章

  1. 【c语言】蓝桥杯算法提高 c++_ch02_02
  2. Nutch2.4 存储方式配置
  3. LeetCode 686. 重复叠加字符串匹配
  4. (三)、dubbo环境的搭建
  5. 实例分解神经网络反向传播算法(转)
  6. linux sort命令 性能,Linux sort 命令简单使用
  7. 每天Leetcode 刷题 初级算法篇-设计问题-最小栈
  8. eventlistener java_EventListener原理
  9. VS2015 更换exe的图标
  10. Unix文件系统的层次结构
  11. CocosCreator之场景编辑器介绍
  12. winhex 比较详细的图文使用教程
  13. JVM-垃圾回收机制
  14. 大数据查询与处理Pig培训:大数据查询处理技术解析
  15. 为什么边缘概率密度是联合概率密度的积分_看懂蒙特卡洛积分(一) 概率分布变换与随机采样...
  16. wps取消英文首字母大写功能
  17. JRebel启动报错:compile error: cannot find constructor org.zeroturnaround.javarebel.integration.spring
  18. 百度Sugar BI 数据可视化里的标签页组件如何实现
  19. Word——图表如何交叉引用-插入题注-交叉引用
  20. CSS (3) | 盒子

热门文章

  1. MariaDB [Warning] Could not increase number of max_open_files to more than 1024
  2. JAVA获取系统相关的信息
  3. 关于Verilog中begin···end语句执行顺序
  4. 2 -13 作业需求
  5. springboot13 发布和监听事件
  6. study note9
  7. Spring之泛型依赖注入
  8. java中使用jxl导出Excel表格详细通用步骤
  9. AlertView动画
  10. 线程池:ThreadPoolExecutor