实验一@TOC
1、实验目的
1.学会从计算和程序的角度分析问题
2.通过完成本实验,理解计算思维,即从问题出发,通过逐步分析和分解,把原问题转化为可用程序方式解决的问题。在此过程中设计出一个解决方案。
3.进一步理解彩色空间的概念并掌握不同彩色空间转换的基本方程。
3.通过逐步设计程序,掌握编程细节:如查找表的设计,内存分配,对 U 和 V 信号进行下采样,文件读写过程等。掌握程序调试的基本方法。
4.实验设备:安装 Visual Studio 及其他软件的个人计算机。
2.实验原理:
1.彩色空间转换的公式:
Y=0.2990R+0.5870G+0.1140B
R-Y=0.7010R-0.5870G-0.1140B
B-Y=-0.2990R-0.5870G+0.8860B
为了使色差信号的动态范围控制在0.5之间,需要进行归一化,对色差信号引入压缩系数,归一化后的色差信号为:
U=-0.1684R-0.3316G+0.5B
V=0.5R-0.4187G-0.0813B
将其8比特量化并且将UV信号往上搬移128个电平最后所得公式为:
Y=0.2990R+0.5870G+0.1140B
U=-0.1684R-0.3316G+0.5B+128
V=0.5R-0.4187G-0.0813B+128
yuv2rgb的公式为:
R=Y+1,4020(V-128)
G=Y-0.3441(U-128)-0.7139(V-128)
B=Y-1.7718(U-128)-0.0013(V-128)
在数字电视技术中,rgb信号转化为yuv数字信号传输应当需要以下步骤:
1.色彩空间的变换: Y → R − Y , B − Y Y\rightarrow R-Y,B-Y Y→R−Y,B−Y
2.归一化(控制动态范围): R − Y , B − Y → C r , C b R-Y,B-Y\rightarrow Cr,Cb R−Y,B−Y→Cr,Cb
3.量化:将 ( − 0.5 , 0.5 ) (-0.5,0.5) (−0.5,0.5)的 C r , C b Cr,Cb Cr,Cb信号8比特/10比特量化。
(为了防止传输的信号变动,需要设置几级作为保护带)
然而yuv文件并不像数字电视信号一样需要考虑传输时的电平保护,所以文件转化时并不需要设置保护带。
2.码电平分配:
亮电平信号量化后码电平分配
在对分量信号进行8比特均匀量化时,共分为256个等间隔的量化级。为了防止信号变动造成过载,在256级上端留20级,下端留16级作为信号超越动态范围的保护带。
色差信号量化后码电平分配
色差信号经过归一化处理后,动态范围为-0.5-0.5,让色差零电平对应码电平128,
色差信号总共占225个量化级。在256级上端留15级,下端留16级作为信号超越动态范围的保护带。
3.色度格式
4:2:0格式是指色差信号U,V的取样频率为亮度信号取样频率的四分之一,在水平方向和垂直方向上的取样点数均为Y的一半。
三、rgb2yuv实验:
1.代码调试:
void InitLookupTable()
{
int i;
for (i = 0; i < 256; i++) RGBYUV02990[i] = (float)0.2990 * i;
for (i = 0; i < 256; i++) RGBYUV05870[i] = (float)0.5870 * i;
for (i = 0; i < 256; i++) RGBYUV01140[i] = (float)0.1140 * i;
for (i = 0; i < 256; i++) RGBYUV01684[i] = (float)0.1684 * i;
for (i = 0; i < 256; i++) RGBYUV03316[i] = (float)0.3316 * i;
for (i = 0; i < 256; i++) RGBYUV04187[i] = (float)0.4187 * i;
for (i = 0; i < 256; i++) RGBYUV00813[i] = (float)0.0813 * i;
}
2.实验结果
跑通代码,使用YUVviewerPlus显示输出结果如下:
四、yuv2rgb实验:
1.代码实现:
主函数的实现与所提供的并无太大差别,稍微改动即可,思路是设置三个yBuf,uBuf,vBuf分别存放读入的YUV文件数据,用rgbBuf存放最后生成的rgb文件数据。
#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