DCT (离散余弦变换)
JPEG 里, 要对数据压缩, 先要做一次 DCT 变换. DCT 变换的原理, 涉及到数学
知识, 这里我们不必深究. 反正和傅立叶变换(学过高数的都知道) 是差不多了. 经过
这个变换, 就把图片里点和点间的规律呈现出来了, 更方便压缩.JPEG 里是对每 8x8
个点为一个单位处理的. 所以如果原始图片的长宽不是 8 的倍数, 都需要先补成 8
的倍数, 好一块块的处理. 按从左到右, 从上到下的次序排列
JPEG 编码时使用的是 Forward DCT (FDCT) 解码时使用的 Inverse DCT (IDCT)
下面给出公式:
FDCT:
7 7 2*x+1 2*y+1
F(u,v) = alpha(u)*alpha(v)* sum sum f(x,y) * cos (------- *u*PI)* cos (------ *v*PI)
x=0 y=0 16 16
u,v = 0,1,...,7
{ 1/sqrt(8) (u==0)
alpha(u) = {
{ 1/2 (u!=0)
void CLCLR_Deblocking::DCT(double f[][8], double F[][8])
{
int u,v,i,j;
for(u=0;u<8;u++)
{
for(v=0;v<8;v++)
{
double k=0.0;
if(u==0&&v==0)
{
for(i=0;i<8;i++)
for(j=0;j<8;j++)
k=k+0.125*f[i][j];
F[u][v]=k;
}
if(u==0&&v!=0)
{
for(i=0;i<8;i++)
for(j=0;j<8;j++)
k=k+sqrt(2.0)/8.0*f[i][j]*cos((2*j+1)*v*PI/16);
F[u][v]=k;
}
if(u!=0&&v==0)
{
for(i=0;i<8;i++)
for(j=0;j<8;j++)
k=k+sqrt(2.0)/8.0*f[i][j]*cos((2*i+1)*u*PI/16);
F[u][v]=k;
}
if(u!=0&&v!=0)
{
for(i=0;i<8;i++)
for(j=0;j<8;j++)
k=k+0.25*f[i][j]*cos((2*i+1)*u*PI/16)*cos((2*j+1)*v*PI/16);
F[u][v]=k;
}
}
}
}
IDCT:
7 7 2*x+1 2*y+1
f(x,y) = sum sum alpha(u)*alpha(v)*F(u,v)*cos (------- *u*PI)* cos (------ *v*PI)
u=0 v=0 16 16
x,y=0,1...7
/*********************************************** *对8*8数据F[u][v]进行IDCT变化生成f[i][j] *应用公式: *f(x,y) =sum alpha(u)*alpha(v)*F(u,v)*cos (------- *u*PI)* cos (------ *v*PI) ************************************************/ void CLCLR_Deblocking::IDCT(double f[][8], double F[][8]) { int u,v,i,j; for(i=0;i<8;i++) { for(j=0;j<8;j++) { double k=0.0; for(u=0;u<8;u++) for(v=0;v<8;v++) k=k+xishualpha(u,v)*F[u][v]*cos((2*i+1)*u*PI/16)*cos((2*j+1)*v*PI/16); f[i][j]=k; } } }