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

    现在的视频及通用图像压缩都无法逾越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

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DCT(离散余弦变换)是一种将信号从时域转换到频域的方法,常用于图像和音频处理中。在Python中,可以使用不同的库实现DCT变换。 引用给出了使用OpenCV库函数实现DCT变换的代码示例。首先,将原始图像块数据转换为浮点型,并使用cv2.dct函数进行DCT变换。输出结果是DCT变换后的图像块数据。 引用给出了使用PyTorch库实现DCT变换的代码示例。首先,构造了一个图像块的伪数据,并将其转换为张量。然后,构造了DCT变换系数矩阵,并通过torch.matmul函数执行矩阵乘法,得到DCT变换后的图像块数据。 这两种方法都可以实现DCT变换,具体选择哪一种方法取决于使用的库和具体的需求。 DCT变换在图像处理中有广泛的应用,尤其在JPEG压缩中。通过应用DCT变换,可以将图像转换为频域表示,从而实现对图像的压缩。DCT变换能够将图像中的能量集中在较低频率分量上,这样就可以利用量化技术对高频分量进行更有效的压缩,从而实现较高的压缩比。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【DCT变换】Python矩阵运算实现DCT变换](https://blog.csdn.net/girl_Xiaomin/article/details/131400721)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值