转载自:
离散余弦变换(Discrete cosine Transform)简称DCT。任何连续的实对称函数的傅里叶变换 中只含余弦项,因此余弦变换与傅里叶变换一样有明确 的物理量意义。DCT是先将整体图像分成N×N像素块,然后对N×N像素块逐一进行DCT变换。 由于 大多数图像的高频分量较小,相应于图像高频成分的系数经常为零,加上人眼对高频成分的 失真不太敏感,所以可用更粗的量化,因此传送变换系数所用的数码率要大大小于传送图像 像素所用的数码率。到达接收端后再通过反离散余弦变换回到样值,虽然会有一定的失真 ,但人眼是可以接受的。
这里先帖出4x4DCT/IDCT最简单的实现吧,以后再补上文档和更好的实现方法。
//---------------------------------------
//
// dct.h
//
// Created by Jesse Kuo 2005/1/4
//---------------------------------------
/*
#define pi 3.1415926
static double c[0] = cos(0/8*pi);
static double c[1] = cos(1/8*pi);
static double c[2] = cos(2/8*pi);
static double c[3] = cos(3/8*pi);
static double c[4] = cos(4/8*pi);
static double c[5] = cos(5/8*pi);
static double c[6] = cos(6/8*pi);
static double c[7] = cos(7/8*pi);
static double c[8] = cos(8/8*pi);
static double c[9] = cos(9/8*pi);
static double c[10] = cos(10/8*pi);
static double c[11] = cos(11/8*pi);
static double c[12] = cos(12/8*pi);
static double c[13] = cos(13/8*pi);
static double c[14] = cos(14/8*pi);
static double c[15] = cos(15/8*pi);
*/
static double c[16] = {
1,
0.92387953251128675612818318939679,
0.70710678118654752440084436210485,
0.3826834323650897717284599840304,
0,
-0.3826834323650897717284599840304,
-0.70710678118654752440084436210485,
-0.92387953251128675612818318939679,
-1,
-0.92387953251128675612818318939679,
-0.70710678118654752440084436210485,
-0.3826834323650897717284599840304,
0,
0.3826834323650897717284599840304,
0.70710678118654752440084436210485,
0.92387953251128675612818318939679
};
static double sqar2 = 0.70710678118654752440084436210485;
void kdct4x4(double dct[4][4], double input[4][4])
{
int u,v,m,n;
double tmp = 0.0;
int s1 = 0;
int s2 = 0;
for(u=0;u<4;u++)
for(v=0;v<4;v++)
dct[u][v] = 0.0;
for(u=0;u<4;u++)
for(v=0;v<4;v++)
{
tmp = 0.0;
for(m=0;m<4;m++)
for(n=0;n<4;n++)
{
s1 = ((2*m+1)*u) % 16;
s2 = ((2*n+1)*v) % 16;
tmp += input[m][n] * c[s1] * c[s2] ;
}
dct[u][v] = tmp * 0.5;
}
for(u=0; u< 4; u++)
dct[u][0] = dct[u][0] * sqar2;
for(v=0; v< 4; v++)
dct[0][v] = dct[0][v] * sqar2;
}
void kidct4x4(double dct[4][4], double output[4][4])
{
int u,v,m,n;
double tmp = 0.0;
int s1 = 0;
int s2 = 0;
for(m=0;m<4;m++)
for(n=0;n<4;n++)
output[m][n] = 0.0;
for(m=0;m<4;m++)
for(n=0;n<4;n++)
{
tmp = 0.0;
for(u=1;u<4;u++)
for(v=1;v<4;v++)
{
s1 = ((2*m+1)*u) % 16;
s2 = ((2*n+1)*v) % 16;
tmp += dct[u][v] * c[s1] * c[s2];
}
for(u=1;u<4;u++) //v=0
{
s1 = ((2*m+1)*u) % 16;
tmp += dct[u][0] * c[s1] * sqar2 ;
}
for(v=1;v<4;v++) // u =0
{
s2 = ((2*n+1)*v) % 16;
tmp += dct[0][v] * c[s2] * sqar2 ;
}
//add (0,0)
tmp += dct[0][0] * 0.5;
//copy the data to out buff
output[m][n] = tmp * 0.5 ;
}
}
//--------------------------------------
// File end.
//--------------------------------------
阅读(713) | 评论(0) | 转发(0) |