📄 dctandidct.java
字号:
public class 二维dct变换及idct变化 {
/**
* @param args
* 可以考虑用一个子程序实现dct与idct,就像dft与idft那样
*/
final static int 维数 = 8;
public static void main(String[] args) {
// TODO 自动生成方法存根
int i, j;
二维dct变换及idct变化 ob = new 二维dct变换及idct变化();
int[][] x = {{89,101,114,125,126,115,105,95},
{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,92 },
{88, 107,136,156,155,129,97,75}};
//double[][] x_double = {{}{}{}{}{}{}{}{}{}{}};
int[][] y = new int[维数][维数];
y = ob.dct(x);
System.out.println("dct变换");
for(i = 0; i < 维数; i++){
for(j = 0; j < 维数; j++){
System.out.print(y[i][j] + " ");
}
System.out.println();
}
System.out.println("idct变换");
x = ob.idct(y);
for(i = 0; i < 维数; i++){
for(j = 0; j < 维数; j++){
System.out.print(x[i][j] + " ");
}
System.out.println();
}
}
//接收int型的x[][],得到int型的y[][]
//
public int[][] dct(int[][] x_int){
int i, j;
double[][] x_double = new double[维数][维数];
double[][] y_double = new double[维数][维数];
double[][] c = new double[维数][维数];
double[][] c转置 = new double[维数][维数];
int[][] y_int = new int[维数][维数];
for(i = 0; i < 维数; i++)
for(j = 0; j < 维数; j++){
if(i == 0)
c[i][j] = 1 / Math.sqrt(8);
else
c[i][j] = 1 / 2.0 * Math.cos(i * (2 * j + 1) * Math.PI / 16);
c转置[j][i] = c[i][j];
// 为了减少误差,函数矩阵乘法是接收double型参数的,故将x[][]double化
x_double[i][j] = (double) x_int[i][j];
}
y_double = 矩阵乘法(c, x_double);
y_double = 矩阵乘法(y_double, c转置);
//四舍五入
for(i = 0; i < 维数; i++)
for(j = 0; j < 维数; j++){
y_int[i][j] = (int) (y_double[i][j] + 0.5);
}
return y_int;
}
//接收int型的y[][],得到int型的x[][]
public int[][] idct(int[][] y_int){
int i, j;
double[][] x_double = new double[维数][维数];
double[][] y_double = new double[维数][维数];
int[][] x_int = new int[维数][维数];
double[][] c = new double[维数][维数];
double[][] c转置 = new double[维数][维数];
for(i = 0; i < 维数; i++)
for(j = 0; j < 维数; j++){
if(i == 0)
c[i][j] = 1 / Math.sqrt(8);
else
c[i][j] = 1 / 2.0 * Math.cos(i * (2 * j + 1) * Math.PI / 16);
c转置[j][i] = c[i][j];
// 为了减少误差,函数矩阵乘法是接收double型参数的,故将y[][]double化
y_double[i][j] = (double) y_int[i][j];
}
x_double = 矩阵乘法(c转置, y_double);
x_double = 矩阵乘法(x_double, c);
//四舍五入
for(i = 0; i < 维数; i++)
for(j = 0; j < 维数; j++){
x_int[i][j] = (int) (x_double[i][j] + 0.5);
}
return x_int;
}
//重载 y[][] = a[][] * b[][]
public double[][] 矩阵乘法(double[][] a, double[][] b){
if(a[0].length != b.length)
System.out.println("出错了");
int i, j, k,len_x,len_y;
int len = b.length;//即a的列数 ,b的行数
len_x = a.length;//a的行数。
len_y = b[0].length;//b的列数
double[][] y = new double[len_x][len_y];
for(i = 0; i < len_x; i++)
for(j = 0; j < len_y; j++){
//y[i][j] = 0;因为初始化时y[][] = 0
for(k = 0; k < len; k++)
y[i][j] += a[i][k] * b[k][j];
}
return y;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -