一.实验原理
二.代码实现
1.RGB转YUV实验
(1)rgb2yuv.h
- 创建头文件并声明函数
int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip);
void InitLookupTable();
(2)rgb2yuv.cpp
- 实现将rgb数据转化为yuv数据。
#include "stdlib.h"
#include "rgb2yuv.h"
static float RGBYUV02990[256], RGBYUV05870[256], RGBYUV01140[256];
static float RGBYUV01684[256], RGBYUV03316[256];
static float RGBYUV04187[256], RGBYUV00813[256];//定义查找表所用公式系数的浮点型数组,且数组大小为量化级范围256
int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip)//定义函数,参数包括宽、高、四个缓冲区指针
{
static int init_done = 0;//定义调用查找表时的控制变量,同时初始化为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;//定义buffer指针
unsigned char *sub_u_buf, *sub_v_buf;定义上采样后的U、V缓冲区指针
if (init_done == 0)
{
InitLookupTable();//调用查找表,计算各量化级的公式系数
init_done = 1;
}
if ((x_dim % 2) || (y_dim % 2)) return 1;//判断图像宽、高是否为偶数,从而确定上采样格式
size = x_dim * y_dim;//尺寸变量赋值
y_buffer = (unsigned char *)y_out;
sub_u_buf = (unsigned char *)u_out;
sub_v_buf = (unsigned char *)v_out;
u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));//为上采样后的U、V缓冲区指针分配动态内存
if (!(u_buffer && v_buffer))
{
if (u_buffer) free(u_buffer);
if (v_buffer) free(v_buffer);
return 2;
}
b = (unsigned char *)bmp;
y = y_buffer;
u = u_buffer;
v = v_buffer;
// RGB 转 YUV
if (!flip) {
for (j = 0; j < y_dim; j ++)
{
y = y_buffer + (y_dim - j - 1) * x_dim;
u = u_buffer + (y_dim - j - 1) * x_dim;
v = v_buffer + (y_dim - j - 1) * x_dim;
for (i = 0; i < x_dim; i ++) {
g = b + 1;
r = b + 2;//RGB文件中图像每一像素按B、G、R依次排列
*y = (unsigned char)( RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
*u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2 + 128);
*v = (unsigned char)( (*r)/2 - RGBYUV04187[