DCT / IDCT


/* DCT与IDCT变换的简单实现,不是最优解 */



#include <iostream>
#include <math.h>

using namespace std;

#define NUM 8
#define PI 3.1415926


short round(double a)
{
         if (a >= 0)
         {
                  return (short)(a + 0.5);
         }
         else
         {
                   return (short)(a - 0.5);
         }
}


// DCT - Discrete Cosine Transform

void DCT(short data[NUM][NUM])
{
         short output[NUM][NUM];
         double ALPHA, BETA;
         short u = 0;
         short v = 0;
         short i = 0;
         short j = 0;

         for(u = 0; u < NUM; u++)
         {
                   for(v = 0; v < NUM; v++)
                   {
                          if(u == 0)
                           {
                                     ALPHA = sqrt(1.0 / NUM);
                            }
                            else
                            {
                                     ALPHA = sqrt(2.0 / NUM);
                            }


                            if(v == 0)
                            {
                                     BETA = sqrt(1.0 / NUM);
                            }
                            else
                            {
                                     BETA = sqrt(2.0 / NUM);
                            }

                            double tmp = 0.0;

                            for(i = 0; i < NUM; i++)
                            {
                                     for(j = 0; j < NUM; j++)
                                     {
                                               tmp += data[i][j] * cos((2*i+1)*u*PI/(2.0 * NUM)) * cos((2*j+1)*v*PI/(2.0 * NUM));
                                     }
                            }
                            output[u][v] = round(ALPHA * BETA * tmp);
                   }
         }
         memset(data, 0, NUM * NUM * sizeof(short));
         memcpy(data, output, NUM * NUM * sizeof(short));

}

 
// Inverse DCT (IDCT)

void IDCT(short data[NUM][NUM])
{
         short output[NUM][NUM];
         double ALPHA, BETA;
         short u = 0;
         short v = 0;
         short i = 0;
         short j = 0;

         for(i = 0; i < NUM; i++)
         {
                   for(short j = 0; j < NUM; j++)
                   {
                            double tmp = 0.0;

                            for(short u = 0; u < NUM; u++)
                            {
                                     for(v = 0; v < NUM; v++)
                                     {
                                               if(u == 0)
                                               {
                                                        ALPHA = sqrt(1.0 / NUM);
                                               }
                                               else
                                               {
                                                       ALPHA = sqrt(2.0 / NUM);
                                               }
                                               if(v == 0)
                                               {
                                                        BETA = sqrt(1.0 / NUM);
                                               }
                                               else
                                               {
                                                        BETA = sqrt(2.0 / NUM);
                                               }
                                               tmp += ALPHA * BETA * data[u][v] * cos((2*i+1)*u*PI/(2.0 * NUM)) * cos((2*j+1)*v*PI/(2.0 * NUM));
                                     }
                            }
                            output[i][j] = round(tmp);
                   }
         }
         memset(data, 0, NUM * NUM * sizeof(short));
         memcpy(data, output, NUM * NUM * sizeof(short));
}
 

int   main(void)
{
         short i = 0;
         short j = 0;
         short u = 0;
         short v = 0;   

         // 8 x 8 的图像数据

         short input[NUM][NUM] =
         {
                   { 89, 101, 114, 125, 126, 115, 105, 96 },


                   { 97, 115, 131, 147, 149, 135, 123, 113 },


                   { 114, 134, 159, 178, 175, 164, 149, 137 },


                   { 121, 143, 177, 196, 201, 189, 165, 150 },


                   { 119, 141, 175, 201, 207, 186, 162, 144 },


                   { 107, 130, 165, 189, 192, 171, 144, 125 },


                   { 97, 119, 149, 171, 172, 145, 117, 96 },


                   { 88, 107, 136, 156, 155, 129, 97, 75 }


         };


         DCT(input); // DCT

         cout << "\nThe result of DCT:\n" << endl;

         for(u = 0; u < NUM; u++)
         {
                   for(v = 0; v < NUM; v++)
                   {
                            cout << input[u][v] << '/t';
                   }
                   cout << endl;
         }

         IDCT(input);  // IDCT

         cout << "\nThe result of IDCT:\n" << endl;

         for(i = 0; i < NUM; i++)
         {
                   for(short j = 0; j < NUM; j++)
                   {
                            cout << input[i][j] << '/t';
                   }
                   cout << endl;
         }
system("pause");
         return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值