【数据压缩】Exp01.彩色空间转换——YUV2RGB

【一】.基本原理

这次的实验是将yuv格式的图像转换为rgb格式。两种彩色空间互相转换的公式如下:

1.RGB转YUV:

Y=0.2990*R+0.5870*G+0.1140*B
U=-0.1684*R+-0.3316*G+0.5*B
V=0.5*R-0.4187*G-0.0813*B

2.YUV转RGB:

R = Y+(R-Y) = Y+1.14075(V-128)
G = Y+(G-Y) = Y-0.7169(V-128)-0.3455(U-128)
B = Y+(B-Y) = Y+1.779(U-128)

为了编程实现该功能,首先需要了解的是两种不同格式的文件的数据是如何组织存储的。本次实验的yuv文件是采用4:2:0的采样格式,即色差信号U和V相对于亮度信号Y而言是水平方向2:1,垂直方向2:1采样的。它在文件中是按帧的顺序,先存每一帧的Y分量,接着是U分量,最后是V分量,存完第一帧再按相同的格式存储下一帧。而本实验的RGB文件则是按照G、B、R的顺序,从上到下,从左到右地依次存储将每个像素点的G、B、R的值。

由于代码较长,因此考虑将功能分块,这样可增强代码的可读性而且便于后期代码的管理。

【二】.实验流程分析

在运行程序之前需要对project的一些参数进行设置,main函数的参数有四个,分别为输入的文件名,输出的文件名,图像的宽,图像的高,并将工作路径设为输入文件所在的路径:

第一次运行程序,发现程序虽然通过了编译和链接,但在程序运行过程中,main函数中文件读取中的打印消息打印出来了,但在之后程序运行便崩掉了,因此可能是在调用yuv2rgb这个子函数时出现了问题。经过仔细的检查之后发现,是因为u和v信号的上取样时,其中的指针赋初值时出现了问题。

sq_ubuf和sq_vbuf这两个指针是用来指向上取样后的UV分量,因此它们的初始值不应该与u_buffer和v_buffer指针的地址有关,且上取样时划红线的两行代码忘记加1,导致每四个像素中的第三个像素重复赋值,而第四个像素没有赋值,因此程序不能正常运行。发现该问题后,定义了两个新的指针变量:

修正代码后程序能够正常运行,并成功生成.rgb文件,将该生成的文件用给定的rgb2yuv程序转换为.yuv格式后用yuvplayer播放器查看,效果图如下:

上面的图为原始yuv图像,下面的图为由程序转换后得到的yuv图像,可以清楚地看到图像上有一些噪点,说明程序还是存在问题。初步猜测可能是在进行数据类型强制转换时出现了问题。经过转换公式计算后得到的浮点数的范围可能并不一定咋在0到255之间,将其强制转换为范围在0到255之间的unsigned char型数据会导致数据出错,因此定义了三个浮点型的中间变量,用来判断经转换公式计算得到的数是否在0到255的范围内,若不在此范围内则将超出范围的数据强制置为0或255:

代码经过修改后得到的.rgb文件再经过转换得到的.yuv文件如下:

可以看到噪点已经都被消除,与源图像几乎已无差别。

【三】.实验代码及其分析

下面为修改后的最终代码:

main.app

yuv2rgb.app

yuv2rgb.h

【四】.实验结果及分析

这次实验共用了三张不同的yuv图像进行测试,结果如下:

通过上列图像可以看出,由于对计算后的数据进行了范围的判断以及相应的处理,因此不同亮度的图像都能正常地转换得到预期的结果。

【五】.结论

通过这次的实验,不仅熟悉了编程语言,更重要的是在调试代码的过程中学会如何去找错误和修正错误。在编程的过程中找错误是一个非常重要的能力,只有学会如何去找出错误才有可能得到最后想要的结果。除此之外,用整体的眼光看待问题、分析问题也是十分重要的,这些都是需要我在之后的学习锻炼中不断积累与成长的地方。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值