快速DCT运算(查表替换法)

本文针对视频及通用图像压缩中耗时的DCT运算进行了优化,采用查表替换法显著提升了编解码速度,使得图像压缩过程从原先的数分钟缩短到几秒钟。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    现在的视频及通用图像压缩都无法逾越DCT运算,因为效果好。近来测试编解码发现这一部分非常慢,DCT运算是耗速大户,所以先对其改进,查阅了几乎所有的提速方案,我倾向于查表替换法,这种方法是先将耗时的运算提取出来,先期运算,需要时替换,提高了即时运算速度。

原程序:

void __fastcall CDCT::FDCT(double fOutPut[][8], BYTE bzInPut[][8])//正向离散余玄变换
{
   double ALPHA, BETA, tmp; int u,v,i,j;

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

             if(v == 0)
                BETA = sqrt(1.0 / 8.0);
                else
                BETA = sqrt(2.0 / 8.0);

             tmp = 0.0;
             for(i = 0; i < 8; i++)
             for(j = 0; j < 8; j++)
                {
                   tmp += bzInPut[i][j] * cos((2 * i + 1) * u * PI / 16) * cos((2 * j + 1) * v * PI / 16);
                }
             fOutPut[u][v] = ALPHA * BETA * tmp;
           }
      }
}

void __fastcall CDCT::IDCT(BYTE bzOutPut[][8], int czInPut[][8])//反向离散余玄变换
{
   double ALPHA, BETA, tmp; int u,v,i,j;

   for(i = 0; i < 8; i++)
      {
        for( j = 0; j < 8; j++)
           {
             tmp = 0.0;
             for(u = 0; u < 8; u++)
                {
                  for(v = 0; v < 8; v++)
                     {
                       if(u == 0)
                          ALPHA = sqrt(1.0 / 8.0);
                          else
                          ALPHA = sqrt(2.0 / 8.0);

                       if(v == 0)
                          BETA = sqrt(1.0 / 8.0);
                          else
                          BETA = sqrt(2.0 / 8.0);

                       tmp += ALPHA * BETA * czInPut[u][v] * cos((2 * i + 1) * u * PI / 16) * cos((2 * j + 1) * v * PI / 16);
                     }
                }
             if(tmp < 0) tmp = 0;
             if(tmp > 255) tmp = 255;
             bzOutPut[i][j] = (BYTE)tmp;
           }
      }
}

提速后的:

__fastcall CDCT::CDCT(void)//初始参数
{
   int u,v,i,j;

   C0 = sqrt(1.0 / 8.0);
   C1 = sqrt(2.0 / 8.0);
   for(u = 0; u < 8; u++)
      {
        for(v = 0; v < 8; v++)
           {
             for(i = 0; i < 8; i++)
             for(j = 0; j < 8; j++)
                {
                   C2[u][i] = cos((2 * i + 1) * u * PI / 16.0);
                   C3[v][j] = cos((2 * j + 1) * v * PI / 16.0);
                }
           }
      }
}

void __fastcall CDCT::FDCT(double fOutPut[][8], BYTE bzInPut[][8])//正向离散余玄变换
{
   double ALPHA, BETA, tmp; int u,v,i,j;

   for(u = 0; u < 8; u++)
      {
        for(v = 0; v < 8; v++)
           {
             if(u == 0)
                ALPHA = C0;
                else
                ALPHA = C1;

             if(v == 0)
                BETA = C0;
                else
                BETA = C1;

             tmp = 0.0;
             for(i = 0; i < 8; i++)
             for(j = 0; j < 8; j++)
                {
                   tmp += bzInPut[i][j] * C2[u][i] * C3[v][j];
                }
             fOutPut[u][v] = ALPHA * BETA * tmp;
           }
      }
}

void __fastcall CDCT::IDCT(BYTE bzOutPut[][8], int czInPut[][8])//反向离散余玄变换
{
   double ALPHA, BETA, tmp; int u,v,i,j;

   for(i = 0; i < 8; i++)
      {
        for( j = 0; j < 8; j++)
           {
             tmp = 0.0;
             for(u = 0; u < 8; u++)
                {
                  for(v = 0; v < 8; v++)
                     {
                       if(u == 0)
                         ALPHA = C0;
                         else
                         ALPHA = C1;

                       if(v == 0)
                         BETA = C0;
                         else
                         BETA = C1;

                       tmp += ALPHA * BETA * czInPut[u][v] * C2[u][i] * C3[v][j];
                     }
                }
             if(tmp < 0) tmp = 0;
             if(tmp > 255) tmp = 255;
             bzOutPut[i][j] = (BYTE)tmp;
           }
      }
}

因为做的是一个类,所以在类建立时,初始化了参数,增加了查表替换变量。

double C0,C1,C2[8][8],C3[8][8];

在不改原基础上,进行替换,明显感觉提速,原来压缩一幅图像需要抽袋烟的时间,感觉很漫长,现在几秒,已经有改进啦。别家的瞬间打开,我家的要几秒,这要看视频几秒一帧也太搞笑了,不循规蹈矩将自主就要付出代价。后续还要提速,不然无法实用。

转载于:https://www.cnblogs.com/hbg200/p/9145527.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值