数字图像处理-傅里叶变换,离散余弦变换
##1.傅里叶变换
###1.1. 一维离散傅里叶变换 定义:设$为一维信号的N个采样值,其离散傅立叶变换及其逆变换分别为:
###1.2. 二维离散傅里叶变换 定义:设$为二维图像信号 其离散傅立叶变换及其逆变换分别为:
###1.2. 快速傅里叶变换 设$($为正整数)。下面按照$为奇数和偶数将序列$进行划分,记为
则离散傅里叶变换可以改写成下面的形式
式中,$和$分别是$和$的离散傅里叶变换。一个长度为$的DFT可以转化为两个长度为$的DFT。二维FFT可以由两次一维FFT得到。
###1.3.关键算法 private void setData1(Complex[] data, int power) { this.power = power;
//角度
double angle;
//计算FFT1变换的点数
count = 1 << power;
//分配空间
wc = new Complex[count / 2];
x = new Complex[count];
x1 = new Complex[count];
x2 = new Complex[count];
fd1 = new Complex[count];
//初始化
for (i = 0; i < count / 2; i++)
wc[i] = new Complex();
for (i = 0; i < count; i++)
{
x[i] = new Complex();
x1[i] = new Complex();
x2[i] = new Complex();
fd1[i] = new Complex();
}
//计算加权系数
for (i = 0; i < count / 2; i++)
{
angle = -i * Math.PI * 2 / count;
wc[i].re = Math.cos(angle);
wc[i].im = Math.sin(angle);
}
//将实域点写入x1
for (i = 0; i < count; i++)
x1[i] = data[i];
} 其中,$$$2^{power}=iw或ih$$$,与进行傅里叶变换是行或列有关,Complex表示复数。
##2.离散余弦变换
###2.1.DFT存在的问题
- DFT的参数都是复数,在数据的描述上相当于 实数的两倍。
- 为此,我们希望有一种能够达到相同功能但数 据量又不大的变换。
###2.2.DCT-II公式
###2.3.一维离散余弦变换 一维$点离散余弦变换(DCT)可以表示为: 其中,$是输入时域序列中的第$项,$是输出频域序列中的第$项,系数$定义如下:
一维$点离散余弦逆变换(IDCT)可以表示为:
###2.4.二维离散余弦变换 二维图像$图像块的DCT可以理解为对图像块的每一列进行一维DCT,然后对进行变换的块每列再做一维DCT。表达式如下所示:
###2.5.关键算法 求变换矩阵$
public void coeff(double[][] dct_coef, int n)
{
double sqrt_1 = 1.0 / Math.sqrt(2.0);
for (int i = 0; i < n; i++)
dct_coef[0][i] = sqrt_1;
//初始化DCT系数
for (int i = 1; i < n; i++)
for (int j = 0; j < n; j++)
dct_coef[i][j] = Math.cos(i * Math.PI * (j + 0.5) /((double)n));
}
DCT正变换$
public void dct(double[][] a, double[][] b, double[][] c, int n)
{
double x;
double[][] af = new double[n][n];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
x = 0.0;
for (int k = 0; k < n; k++)
x += a[i][k] * b[k][j];
af[i][j] = x;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
x = 0.0;
for (int k = 0; k < n; k++)
x += c[i][k] * af[k][j];
a[i][j] = 2.0 * x / ((double)n);
}
}
}
其中,$矩阵分别为被变换的矩阵$,变换矩阵的转置$,变换矩阵$