Chinaunix首页 | 论坛 | 博客
  • 博客访问: 42960
  • 博文数量: 21
  • 博客积分: 840
  • 博客等级: 准尉
  • 技术积分: 225
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-24 00:24
文章分类
文章存档

2010年(21)

我的朋友

分类:

2010-06-08 21:01:44

转载自:
  
  离散余弦变换(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) |
给主人留下些什么吧!~~