DCT算法C++实现源码

声明:此代码并非原创,参照网络上一位前辈的代码,但是测试发现他的代码有BUG,修改后贴出已做记录;

 

#include<stdlib.h>
#include<iostream>
#include<math.h>
#include<vector>
#define PI acos(-1)//定义圆周率
using namespace std;

void DCT(vector<vector<float>>& ori, vector<vector<float>>& dct, float N);

int main(void)
{
    const int N = 4;//二维数组的阶数
    //float start[N][N] = { 12,27,3,4,55,6,7,28,9,10,11,12,123,14,65,16 };//二维数组的初始值,可以自己任意设置
    float start[N][N] = { 89.0903,14.9294,81.4285,19.6595,95.9291,25.7508,24.3525,25.1084,54.7216,84.0717,92.9264,61.6045,
        13.8624,25.4282,34.9984,47.3289};//二维数组的初始值,可以自己任意设置
    /*float start[N][N] = { 
        { 52, 55, 61, 66, 70, 61, 64, 73 },

        { 63, 59, 55, 90, 109, 85, 69, 72 },

        { 62, 59, 68, 113, 144, 104, 66, 73 },

        { 63, 58, 71, 122, 154, 106, 70, 69 },

        { 67, 61, 68, 104, 126, 88, 68, 70 },

        { 79, 65, 60, 70, 77, 68,58, 75 },

        { 85, 71, 64, 59, 55, 61, 65, 83 },

        { 87, 79, 69, 68, 65, 76, 78, 94 }
    };*/

    vector<vector<float>> oriMatrix;//原始的二维数组,用容器的方法来定义,方便调试
    vector<vector<float>> dctMatrix;//用来存储经过DCT变换后的二维数组
    vector<float> temp;//temp仅仅是为了用来填充oriMatrix
                       //填充oriMatrix
    for (int i = 0; i < N; i++)
    {
        temp.push_back(0);
    }
    for (int i = 0; i < N; i++)
    {
        oriMatrix.push_back(temp);
    }
    dctMatrix = oriMatrix;//初始化dctMatrix
                          //初始化oriMatrix
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            oriMatrix[i][j] = start[i][j];
        }
    }
    //输出oriMatrix
    cout << "原始二维数组矩阵:" << endl;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            printf("%-10.4f", oriMatrix[i][j]);//每个输出占10个字符,左对齐,保留4位小数
        }
        cout << endl;
    }
    cout << endl;
    DCT(oriMatrix, dctMatrix, N);//调用自己定义的函数
                                 //输出dctMatrix
    cout << "经过DCT变换后的二维数组矩阵:" << endl;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            printf("%-10.4f", dctMatrix[i][j]);
        }
        cout << endl;
    }
    getchar();
    return 0;
}
void DCT(vector<vector<float>>& ori, vector<vector<float>>& dct, float N)//第一个形参是原始二维数组的引用,第二个形参矩阵是经过DCT变换的二维数组的引用,第三个形参是阶数
{
    double pa = (double)1 / sqrt((double)2);
    double pd = 1;
    for (int k = 0; k < N; k++)
    {
        for (int l = 0; l < N; l++)//注意区分字母L和数字1
        {
            for (int m = 0; m < N; m++)
            {
                for (int n = 0; n < N; n++)
                {
                    if ((k==0)&&(l==0))
                    {
                        pd = pa*pa;
                    }
                    else if ((k == 0)||(l == 0))
                    {
                        pd = pa;
                    }else
                    {
                        pd = 1;
                    }
                    dct[k][l] += pd*(2 / N) * (ori[m][n]) * (cos((2 * m + 1) * k * PI / (2 * N))) * (cos((2 * n + 1) * l * PI / (2 * N)));
                }
            }
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值