数据压缩实验一实验报告

1.实验原理

YUV到RGB的转换算法为
R=Y+1.4075(V−128) R = Y + 1.4075(V - 128)
G=Y+0.3455(U−128)−0.7169(V−128) G=Y + 0.3455(U - 128) - 0.7169(V - 128)
B=Y+1.779(U−128) B=Y + 1.779(U - 128)
分析
此时的U、V实际上是Cb和Cr,为把(R-Y)和(B-Y)的动态范围控制在±350mV内,引入压缩系数,可以得到公式
Cr=0.713(R-Y)
Cb=0.564(B-Y)
又为了便于数字化处理,还要将Cr、Cb引入350mV的偏置,又由于经过8比特量化,色差信号经过归一化处理后,动态范围为-0.5-0.5,让色差零电平对应码电平128。所以公式变为
V=0.713(R-Y)+128
U=0.564(B-Y)+128
经过方程式的计算,可以得到最后的公式

RGB和YUV彩色空间基本原理

RGB彩色空间存储方式是每一个像素点都按照B、G、R的顺序进行存储,每一帧占用空间为width * height * 3个字节的空间。YUV彩色空间存储方式为每一帧的YUV分开存储,每一帧Y占用的空间为width * height,每一帧U和V所占用的空间分别为width * height /4。

取样格式

读取的图片为YUV空间,取样格式为4:2:0,即V和U的水平和垂直采样点数均为Y的一半。但要生成的RGB文件的取样格式为4:4:4,这就要求我们对给定的Y保持不变,对给定的U和V进行上采样,使其可与RGB的采样空间相同。 根据将RGB转成YUV的实验中下采样的方法,我采用的方法是用指针指向yuv文件中的u、v,并开辟两个128*128的空间存*储文件中的u、v。同时还开辟了两个256*256的空间,将一个指向给定uv指针的内容赋值给新的四个像素块,详见具体代码。

2.实验的流程分析

  1. 程序初始化(打开两个文件、定义变量和缓冲区 等)
  2. 读取YUV文件,抽取YUV数据写入缓冲区
  3. 调用YUV2RGB的函数实现YUV到RGB数据的转 换
  4. 写RGB文件
  5. 程序收尾工作(关闭文件,释放缓冲区)

命令行参数的设置
project->properties->Debugging->
Working Directory&Command Arguments

3.重要代码及分析

重要代码通过高亮标出

yuv转为rgb的函数代码:yuv2rgb.cpp

#include "stdlib.h"
#include "yuv2rgb.h"static float RGBYUV14075[256], RGBYUV03455[256];
static float RGBYUV07169[256], RGBYUV17790[256];int YUV2RGB(int x_dim, int y_dim, void *bmp, void *y_in, void *u_in, void *v_in, int flip)
{static int init_done = 0;long i, j, size;unsigned char *r, *g, *b;unsigned char *y, *u, *v;unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv;unsigned char *y_buffer, *u_buffer, *v_buffer;unsigned char *sub_u_buf, *sub_v_buf;if (init_done == 0){InitLookupTable();init_done = 1;}// check to see if x_dim and y_dim are divisible by 2if ((x_dim % 2) || (y_dim % 2)) return 1;size = x_dim * y_dim;// allocate memoryy_buffer = (unsigned char *)y_in;sub_u_buf = (unsigned char *)u_in;sub_v_buf = (unsigned char *)v_in;u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));if (!(u_buffer && v_buffer)){if (u_buffer) free(u_buffer);if (v_buffer) free(v_buffer);return 2;}b = (unsigned char *)bmp;g = b + 1;r = b + 2;y = y_buffer;u = u_buffer;v = v_buffer;
        for (j = 0; j < y_dim / 2; j++){psu = sub_u_buf + j * x_dim / 2;//128*128psv = sub_v_buf + j * x_dim / 2;pu1 = u_buffer + 2 * j * x_dim;pu2 = u_buffer + (2 * j + 1) * x_dim;pv1 = v_buffer + 2 * j * x_dim;pv2 = v_buffer + (2 * j + 1) * x_dim;for (i = 0; i < x_dim / 2; i++){*pu1 = *psu;*(pu1 + 1) = *psu;*pu2 = *psu;*(pu2 + 1) = *psu;*pv1 = *psv;*(pv1 + 1) = *psv;*pv2 = *psv;*(pv2 + 1) = *psv;psu++;psv++;pu1 += 2;pu2 += 2;pv1 += 2;pv2 += 2;/*为了将yuv的取样空间由4:2:0变为4:4:4,就要将一个像素块的值赋给四个像素,psu指针指向的是输入的u的空间,将psu指针指向的一个值赋给新开辟空间中的四个像素,比如将psu指向的第一个值赋给第一行的第一、二个值,即pu1和pu1+1及第二行中的第一二个值pu2和pu2+1。然后psv指针指向的是输入的v的空间。*/}}
        for (i = 0; i < size; i++){g = b + 1;r = b + 2;float tmp;/*r的数据类型为unsigned char,范围为0~255,如果直接进行计算则会出现溢出现象,比如计算得出256,则会变为0,因此通过设置浮点型中间变量tmp防止数据的溢出*/tmp= (*y + RGBYUV14075[*v]);if (tmp > 255) { tmp = 255; }if (tmp < 0) { tmp = 0; }*r = (unsigned char)tmp;tmp = (*y - RGBYUV03455[*u] - RGBYUV07169[*v]);if (tmp > 255) { tmp = 255; }if (tmp < 0) { tmp = 0; }*g = (unsigned char)tmp;tmp = (*y + RGBYUV17790[*u]);if (tmp > 255) { tmp = 255; }if (tmp < 0) { tmp = 0; }*b = (unsigned char) tmp;b += 3;y++; u++; v++;}return 0;}
    /*采用部分查找表法,提高运行效率*/void InitLookupTable(){int i;for (i = 0; i < 256; i++) RGBYUV14075[i] = (float)1.0475 * (i-128);for (i = 0; i < 256; i++) RGBYUV03455[i] = (float)0.3455 * (i-128);for (i = 0; i < 256; i++) RGBYUV07169[i] = (float)0.7169 * (i-128);for (i = 0; i < 256; i++) RGBYUV17790[i] = (float)1.779 * (i-128);}

主函数

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include"yuv2rgb.h"#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)
{u_int frameWidth = 352;u_int frameHeight = 240;bool flip =TRUE;//unsigned int i;/* internal variables */
char* rgbFileName = NULL;
char* yuvFileName = NULL;
FILE* rgbFile = NULL;
FILE* yuvFile = NULL;
u_int8_t* rgbBuf = NULL;
u_int8_t* yBuf = NULL;
u_int8_t* uBuf = NULL;
u_int8_t* vBuf = 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]);
        /* 打开yuv文件*/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 */
rgbBuf = (u_int8_t*)malloc(frameWidth * frameHeight * 3);/* get the output buffers for a frame */
yBuf = (u_int8_t*)malloc(frameWidth * frameHeight);
uBuf = (u_int8_t*)malloc((frameWidth * frameHeight) / 4);
vBuf = (u_int8_t*)malloc((frameWidth * frameHeight) / 4);while ((fread(yBuf, 1, frameWidth * frameHeight , yuvFile))&&(fread(uBuf, 1, frameWidth * frameHeight/4, yuvFile))&&(fread(vBuf, 1, frameWidth * frameHeight/4, yuvFile)))
{if (YUV2RGB(frameWidth, frameHeight, rgbBuf, yBuf, uBuf, vBuf, flip)){printf("error");return 0;}fwrite(rgbBuf, 1, frameWidth * frameHeight * 3, rgbFile);printf("\r...%d", ++videoFramesWritten);
}printf("\n%u %ux%u video frames written\n",videoFramesWritten, frameWidth, frameHeight);
     /*释放开辟的内存空间和关闭打开的文件*/if(rgbBuf!=NULL){free(rgbBuf);}if(yBuf!=NULL){free(yBuf);}if(uBuf!=NULL){free(uBuf);}if(vBuf!=NULL){free(vBuf);}if(yuvFile!=NULL){fclose(yuvFile);}if(rgbFile!=NULL){fclose(rgbFile);}return (0);

}

4.实验结果及分析

错误及调试

1.程序build后没有报错,但在运行过程中出现了breakpoint,经过F11进入main函数,F10进行分步运行后,在main函数中发现错误,释放空间时多次释放rgb空间,而没有释放y、u、v的空间。

2.程序运行后,出现的测试yuv图像所有像素的yuv值均相同,通过检查,发现是yuv指针都始终指向第一个像素点,指针没有移动,后来通过y++,u++,v++的语句移动指针。

3.没有设置tmp为中间变量时出现少量溢出错误,在最终呈现的test。yuv图像上出现蓝色的小色块。以下是对比图。 生成的test图像:

最后结果


  1. 2.

数据压缩实验一实验报告相关推荐

  1. vs2010用c语言实现数据转换成图片,数据压缩第二次实验报告——用C语言实现bmp to yuv的图片格式转化...

    实验目标 实验主要要求将图片格式从BMP到YUV的转化,并生成含有至少五幅图片不少于200帧的图像流. 实验原理 一.BMP图像简介: 典型的BMP图像文件由四部分组成(部分摘自360百科对BMP的定 ...

  2. labview 霍夫曼树_哈夫曼树编码实验报告_信息论与编码实验2 实验报告_信息论与编码报告...

    huffman编码C语言实验报告 今日推荐 180份文档 2014...4页 1下载券 安卓版100 doors 2攻略1... 3页 1下载券 <逃脱本色>doors....语文教育实习 ...

  3. 周信东c语言实验二实验报告,周信东主编最新版C语言程序设计基础实验一实验报告.doc...

    周信东主编最新版C语言程序设计基础实验一实验报告.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我 ...

  4. c语言实验七实验报告,C语言实验七 数 实验报告.doc

    C语言实验七 数 实验报告 C语言程序设计 实 验 报 告 实验题目 实验七 函数 实验目的 掌握函数定义的方法: 掌握函数实参与形参的对应关系,以及值传递的方式. 掌握函数的嵌套调用和递归调用的方法 ...

  5. 大学计算机实验教程实验报告2.2,大学计算机实验2-实验报告.pdf

    大学计算机实验2-实验报告 深 圳 大 学 实 验 报 告 课程名称: 计算机导论 实验名称: 操作系统与工具软件 学院: 建筑与城市规划学院 专业: 建筑学 报告人: XXX 学号: 2015XXX ...

  6. 2017-2018-1 20162306 实验五实验报告

    2017-2018-1 20162306 实验五实验报告 实验五-0-分析系统架构 精灵类ISprite:所有的类都继承精灵类. 战斗机类CombatAircraft:首先定义一架战斗机,通过获取坐标 ...

  7. 计算机网络实验设计应用题,计算机网络实验三实验报告.doc

    计算机网络实验三实验报告 实验综合成绩 (百分制) 实验评阅教师签名其中实验态度优良中及格不及格实验报告优良中及格不及格 实 验 报 告 实验时间: 2015年 12 月 24日 实验运行环境 win ...

  8. 20145315 《Java程序设计》实验五实验报告

    20145315 <Java程序设计>实验五实验报告 实验五 Java网络编程 我负责服务器部分,王嘉澜负责客户端部分:http://www.cnblogs.com/SJZGM10/p/5 ...

  9. 计算机组成原理实验 组装实验报告,计算机组成原理实验一实验报告..doc

    计算机组成原理实验一实验报告. 实验一 运算器实验 算术逻辑运算器 实验目的: 掌握算术逻辑运算器单元ALU(74LS181)的工作原理 掌握简单运算器的数据传送通道 验算由74LS181等组合逻辑电 ...

最新文章

  1. Java 注册SIGINT信号,处理CTRL+C
  2. 使用maven下载依赖包及maven常见问题汇总
  3. mint-ui的Loadmore组件使用示例
  4. Transformer-XL解读(论文 + PyTorch源码)
  5. python opencv resize函数_Python OpenCV中的resize()函数的使用
  6. from 下拉框多个值提交_Git commit 多行信息提交
  7. sql server 日期类型
  8. mysql数据存储到指定位置_Mysql数据库表分区存储到指定磁盘路径
  9. tomcat基础架构剖析
  10. ##(C语言) CSP 201612-2 工资计算(打表法)(100分)
  11. iOS 使用NSUserdefault 保存自定义的 对象
  12. 构建自己的PHP框架(MVC)
  13. Keras ImageDataGenerator参数
  14. 2017大学网考计算机b,(热)2017年4月网考 大学英语b网考 电大英语网考 计算机应用.doc...
  15. C语言实验-偶数数位求和
  16. 教师资格证高中计算机资料,教师资格考试高中信息技术试题
  17. 基于流计算 Oceanus 和 Elasticsearch Service 构建百亿级实时监控系统
  18. Android px转dip px转sp法则
  19. 武汉科技大学计算机科学与技术分数,2019武汉科技大学研究生分数线汇总(含2016-2019历年复试)...
  20. 【译】.NET 7 中的性能改进(十一)

热门文章

  1. 角互补三角形面积公式的证明过程
  2. Mac使用svn提交代码
  3. 请详细阐述摩洛哥的婚姻制度
  4. 谁说技术大会只是演讲者的舞台?来Pworld2016,不止让你“听”!
  5. vue路由的模式 以及原理 区别
  6. nginx配置vhost
  7. string deseq2
  8. 带有RESTEasy + JAXB + Jettison的JSON示例
  9. 【MARK】个人装机软件备份(上)
  10. 安装VMware,创建虚拟化服务器,配置虚拟化服务器网络,linux安装Mysql