图像处理MFC学习(7)——实现8*8数组的DCT、IDCT

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;
		
		}
		
		
	}
}

  


我抬头仰望星空不是为了摘取流星,而是为了一个永不屈服的梦想。
原文地址:https://www.cnblogs.com/happycaoyue/p/3045068.html