声明:此代码并非原创,参照网络上一位前辈的代码,但是测试发现他的代码有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)));
}
}
}
}
}