java中DCT和IDCT算法的问题
这里我有我的DCT算法类和“applyDCT”和“applyDCT”方法。从技术上讲,在对0到255之间的2x2随机整数表进行正向DCT(离散余弦变换)后,然后立即对这些数字进行反向DCT,我们应该回到最初的整数。就我而言,情况并非如此。我做错了什么java中DCT和IDCT算法的问题,java,algorithm,dct,Java,Algorithm,Dct,这里我有我的DCT算法类和“applyDCT”和“applyDCT”方法。从技术上讲,在对0到255之间的2x2随机整数表进行正向DCT(离散余弦变换)后,然后立即对这些数字进行反向DCT,我们应该回到最初的整数。就我而言,情况并非如此。我做错了什么 public class DCT { private static final int N = 2; private double[] c = new double[N]; public DCT() {
public class DCT {
private static final int N = 2;
private double[] c = new double[N];
public DCT() {
this.initializeCoefficients();
}
private void initializeCoefficients() {
for (int i=1;i<N;i++) {
c[i]=1;
}
c[0]=1/Math.sqrt(2.0);
}
public double[][] applyDCT(double[][] f) {
double[][] F = new double[N][N];
for (int u=0;u<N;u++) {
for (int v=0;v<N;v++) {
double sum = 0.0;
for (int i=0;i<N;i++) {
for (int j=0;j<N;j++) {
sum+=Math.cos(((2*i+1)/(2.0*N))*u*Math.PI)*Math.cos(((2*j+1)/(2.0*N))*v*Math.PI)*f[i][j];
}
}
sum*=((c[u]*c[v])/4.0);
F[u][v]=sum;
}
}
return F;
}
public double[][] applyIDCT(double[][] F) {
double[][] f = new double[N][N];
for (int u=0;u<N;u++) {
for (int v=0;v<N;v++) {
double sum = 0.0;
for (int i=0;i<N;i++) {
for (int j=0;j<N;j++) {
sum+=((c[u]*c[v]))*Math.cos(((2*i+1)/(2.0*N))*u*Math.PI)*Math.cos(((2*j+1)/(2.0*N))*v*Math.PI)*F[i][j];
}
}
sum/=4.0;
//sum*=((c[u]*c[v])/4.0);
f[u][v]=sum;
}
}
return f;
}
}
如上所示,“返回到f”最初没有显示f中包含的相同值…我已经解决了这个问题,如果我的问题不清楚,我很抱歉,但这里有一个不正确的地方:IDCT方法必须在循环的I和j内有系数:
public double[][] applyIDCT(double[][] F) {
double[][] f = new double[N][N];
for (int i=0;i<N;i++) {
for (int j=0;j<N;j++) {
double sum = 0.0;
for (int u=0;u<N;u++) {
for (int v=0;v<N;v++) {
sum+=(c[u]*c[v])/4.0*Math.cos(((2*i+1)/(2.0*N))*u*Math.PI)*Math.cos(((2*j+1)/(2.0*N))*v*Math.PI)*F[u][v];
}
}
f[i][j]=Math.round(sum);
}
}
return f;
}
变成这样:
(2*c[u]*c[v])/Math.sqrt(M*N)
其中M和N是表格的尺寸
以下是2x2数据块的结果:
Original values
---------------
54.0 => f[0][0]
35.0 => f[0][1]
128.0 => f[1][0]
185.0 => f[1][1]
From f to F
-----------
200.99999999999994 => F[0][0]
-18.99999999999997 => F[0][1]
-111.99999999999997 => F[1][0]
37.99999999999999 => F[1][1]
Back to f
---------
54.0 => f[0][0]
35.0 => f[0][1]
128.0 => f[1][0]
185.0 => f[1][1]
输入案例是什么,预期结果是什么,实际结果是什么?您是否尝试过在琐碎的输入案例(例如[1 0;0 0])上运行每一个例程以找出哪一个是错误的?当您说您没有得到原始整数时,会得到什么结果?可能会引入一些浮点舍入错误。DCT本身是有损的。您需要修改DCT(无损DCT)以获得无损(可逆)操作。@osgx:DCT没有损耗(除非您谈论的是舍入误差)。@osgx:那么您不妨将DFT称为“有损耗”!MDCT同样“有损”;它只是有稍微不同的基函数。有些具有整数系数的DCT变体可以在某些情况下使用(脑海中浮现的是H.264),但它们具有不同的数学特性,这可能不适用于OP。
(c[u]*c[v])/4.0)
(2*c[u]*c[v])/Math.sqrt(M*N)
Original values
---------------
54.0 => f[0][0]
35.0 => f[0][1]
128.0 => f[1][0]
185.0 => f[1][1]
From f to F
-----------
200.99999999999994 => F[0][0]
-18.99999999999997 => F[0][1]
-111.99999999999997 => F[1][0]
37.99999999999999 => F[1][1]
Back to f
---------
54.0 => f[0][0]
35.0 => f[0][1]
128.0 => f[1][0]
185.0 => f[1][1]