DCT运算实现,其原理是离散余弦算法。将信号转到频域中。
以下代码经验证是正确的
代码如下,包括对一维数据和二维数据:
<pre name="code" class="java">/**
* author:vivian
* 时间:2015.5.28
* 版本:第一版
* 功能:8点快速傅里叶运算,用的是蝶形运算方法
*
* 各方法的功能
* 1)IntDCT1D针对的是一维的数据,进行8点蝶形运算
* 2)I_IntDCT1D一维数据的8点蝶形逆运算
* 3)IntDCT2D针对的是二维的数据,进行8点蝶形运算
* 4)I_IntDCT1D二维数据的8点蝶形逆运算*/
public class DCT2D{
public void IntDCT1D(int data[])
{
input x0 x1 ... x7
output X0 X2 X4 X6 X1 X3 X5 X7
int datatmp[] = new int [8];
datatmp[0] = data[0] + data[7];
datatmp[1] = data[1] + data[6];
datatmp[2] = data[2] + data[5];
datatmp[3] = data[3] + data[4];
datatmp[4] = data[3] - data[4];
datatmp[5] = data[2] - data[5];
datatmp[6] = data[1] - data[6];
datatmp[7] = data[0] - data[7];
//蝶形运算结束
data[0] = datatmp[0] + datatmp[3];
data[1] = datatmp[1] + datatmp[2];
data[2] = datatmp[1] - datatmp[2];
data[3] = datatmp[0] - datatmp[3];
data[0] += data[1]; data[0] = X0
data[1] = - data[1] + ((data[0])>>1); /// data[1] = X4
data[3] = data[3] - (data[2] >>1) - (data[2] >>3);
data[2] += data[3];
data[3] = data[3] - (data[2] >>1) - (data[2] >>3);
// data[2] = X2 data[3] = X6
datatmp[5] = datatmp[5] - (datatmp[6] >>1) + (datatmp[6] >>4);
datatmp[6] = datatmp[6] + (datatmp[5] >>1) + (datatmp[5] >>2);
datatmp[5] = - datatmp[5] + (datatmp[6] >>1) - (datatmp[6] >>4);
data[4] = datatmp[4] + datatmp[5];
data[5] = datatmp[4] - datatmp[5];
data[6] = -datatmp[6] + datatmp[7];
data[7] = datatmp[6] + datatmp[7];
data[7] = data[7] - (data[4] >>1) -(data[4] >>2) -(data[4] >>4);
data[4] = data[4] + data[7];
data[7] = data[7] - (data[4] >>1) -(data[4] >>2) -(data[4] >>4);
// data[4] = X1 data[7] = X7
data[6] = data[6] - (data[5] >>2);
data[5] = data[5] + (data[6] >>1);
data[6] = data[6] - (data[5] >>2);
// data[5] = X3 data[7] = X5
/* datatmp[0] = data[0]; datatmp[1] = data[2];
datatmp[2] = data[1]; datatmp[3] = data[3];
datatmp[4] = data[4]; datatmp[5] = data[6];
datatmp[6] = data[5]; datatmp[7] = data[7];
*/
datatmp[0] = data[0]; datatmp[1] = data[4];
datatmp[2] = data[2]; datatmp[3] = data[6];
datatmp[4] = data[1]; datatmp[5] = data[5];
datatmp[6] = data[3]; datatmp[7] = data[7];
int i;
for (i=0; i<8; i++) data[i] = datatmp[i];
}
void I_IntDCT1D(int data[])
{
///
/// input X0, X2, X4, X6, X1, X3, X5, X7
output x0, x1,x2, ..., x7
int datatmp[] = new int [8];
int i;
for (i=0; i<8; i++) datatmp[i] = data[i];
data[0] = datatmp[0]; data[1] = datatmp[2];
data[2] = datatmp[4]; data[3] = datatmp[6] ;
data[4] = datatmp[1]; data[5] = datatmp[3];
data[6] = datatmp[5]; data[7] = datatmp[7];
datatmp[1] = - data[2] + (data[0]>>1);
datatmp[0] = data[0] - datatmp[1];
datatmp[3] = data[3] + (data[1] >>1) +(data[1] >>3);
datatmp[2] = data[1] - datatmp[3];
datatmp[3] = datatmp[3] +(datatmp[2] >>1) +(datatmp[2] >>3);
datatmp[6] = data[5] + (data[6] >>2);
datatmp[5] = data[6] - (datatmp[6] >>1);
datatmp[6] = datatmp[6] + (datatmp[5] >>2);
datatmp[7] = data[7] + (data[4] >>1) + (data[4] >>2) + (data[4] >>4);
datatmp[4] = data[4] - datatmp[7];
datatmp[7] = datatmp[7] + (datatmp[4] >>1) + (datatmp[4] >>2) + (datatmp[4] >>4);
// four inverse lifting step
data[0] = (datatmp[0] + datatmp[3]) >>1;
data[3] = (datatmp[0] - datatmp[3]) >>1;
data[1] = (datatmp[1] + datatmp[2]) >>1;
data[2] = (datatmp[1] - datatmp[2]) >>1;
data[4] = (datatmp[4] + datatmp[5]) >>1;
data[5] = (datatmp[4] - datatmp[5]) >>1;
data[6] = (- datatmp[6] + datatmp[7]) >>1;
data[7] = (datatmp[6] + datatmp[7]) >>1;
// four inverse butterfly
data[5] = - data[5] + (data[6] >>1) - (data[6] >>4);
data[6] = data[6] - (data[5] >>1) - (data[5] >>2);
data[5] = data[5] + (data[6] >>1) - (data[6] >>4);
/
datatmp[0] = (data[0] + data[7]) >>1;
datatmp[1] = (data[1] + data[6]) >>1;
datatmp[2] = (data[2] + data[5]) >>1;
datatmp[3] = (data[3] + data[4]) >>1;
datatmp[4] = (data[3] - data[4]) >>1;
datatmp[5] = (data[2] - data[5]) >>1;
datatmp[6] = (data[1] - data[6]) >>1;
datatmp[7] = (data[0] - data[7]) >>1;
//int i;
for(i=0; i<8; i++) data[i] = datatmp[i];
}
public void IntDCT2D(int data[][], int height, int width)
{
int nheight, nwidth;
int i, j, k, l;
int ni, nj; //纪录处理数据的位置
int datatmp[] = new int [8];
nheight = height >>3;
nwidth = width >>3;
ni = 0;
for (i=0; i<nheight; i++)
{
nj = 0;
for (j=0; j<nwidth; j++)
{
//对行做变换
for (k=0; k<8; k++)
{
for (l=0; l<8; l++)
datatmp[l] = data[ni+k][nj+l];
IntDCT1D(datatmp);
for (l=0; l<8; l++)
data[ni+k][nj+l] = datatmp[l];
}
对列做变换
for (k=0; k<8; k++)
{
for (l=0; l<8; l++)
datatmp[l] = data[ni+l][nj+k];
IntDCT1D(datatmp);
for (l=0; l<8; l++)
data[ni+l][nj+k] = datatmp[l];
}
nj = nj + 8;
}
ni = ni + 8;
}
}
public void I_IntDCT2D(int data[][], int height, int width)
{
int nheight, nwidth;
int i, j, k, l;
int ni, nj; //纪录处理数据的位置
int datatmp[] = new int [8];
nheight = height >>3;
nwidth = width >>3;
ni = 0;
for (i=0; i<nheight; i++)
{
nj = 0;
for (j=0; j<nwidth; j++)
{
对列做反变换
for (k=0; k<8; k++)
{
for (l=0; l<8; l++)
datatmp[l] = data[ni+l][nj+k];
I_IntDCT1D(datatmp);
for (l=0; l<8; l++)
data[ni+l][nj+k] = datatmp[l];
}
//对行做反变换
for (k=0; k<8; k++)
{
for (l=0; l<8; l++)
datatmp[l] = data[ni+k][nj+l];
I_IntDCT1D(datatmp);
for (l=0; l<8; l++)
data[ni+k][nj+l] = datatmp[l];
}
nj = nj + 8;
}
ni = ni + 8;
}
}
}