离散傅立叶变换的实现

来源:互联网 发布:mac复制图片 编辑:程序博客网 时间:2024/06/06 14:15

转:http://dsqiu.iteye.com/blog/1636888

研究过离散傅里叶变换的,都会觉得离散余弦变换的会更简单,不过不知道为什么网上却没有像离散傅里叶变换那样多的介绍,还得下次找本书好好钻研,后再补充。

二维离散余弦变换的正变换公式为:

在图像的压缩编码中,N一般取8.

二维DCT的反变换公式为:

以上各式中的系数:

 

基于DCT的JPEG图像压缩编码理论算法 基于DCT编码的JPEG编码压缩过程框图,如图1所示。


图1  基于DCT编码的JPEG压缩过程简化图

上图是基于DCT变换的图像压缩编码的压缩过程,解压缩与上图的过程相反。

在编码过程中,首先将输入图像颜色空间转换后分解为8×8大小的数据块,然后用正向二维DCT把每个块转变成64个DCT系数值,其中1个数值是直流(DC)系数,即8×8空域图像子块的平均值,其余的63个是交流(AC)系数,接下来对DCT系数进行量化,最后将变换得到的量化的DCT系数进行编码和传送,这样就完成了图像的压缩过程。

从原理上讲可以对整幅图像进行DCT变换,但由于图像各部位上细节的丰富程度不同,这种整体处理的方式效果不好。为此,发送者首先将输入图像分解为8*8或16*16块,然后再对每个图像块进行二维DCT变换,接着再对DCT系数进行量化、编码和传输;接收者通过对量化的DCT系数进行解码,并对每个图像块进行的二维DCT反变换。最后将操作完成后所有的块拼接起来构成一幅单一的图像。

所以DCT是对二维像素数组进行处理,下面附上程序:

* in_image  输入图像矩阵   
 * iw, ih    输入图像宽高   
 * bsize     bsizeXbsize图像块DCT变换   
 * type      type = 1为正DCT变换, type =-1为逆变换   
 *------------------------------------------------------------*/   
public double[][] dctTrans(double[][] img, int iw, int ih, int bsize, int type)   
{   
    int iter_num = 256 / bsize;   
    dct_image = new double[iw][ih];   
    dct_coef  = new double[bsize][bsize];   
    dct_coeft = new double[bsize][bsize];   
    image = new double[bsize][bsize];   
       
    coeff(dct_coef, bsize);   
       
    //定义转置矩阵系数   
    for (int i = 0; i < bsize; i++)   
        for (int j = 0; j < bsize; j++)   
            dct_coeft[i][j] = dct_coef[j][i];   
  
    if (type == 1)   
    {              
        for (int j = 0; j < iter_num; j++)   
        {   
            for (int i = 0; i < iter_num; i++)   
            {   
                //取bsizeXbsize图像块image[][]   
                for (int k = 0; k < bsize; k++)   
                    for (int l = 0; l < bsize; l++)                               
                        image[k][l] = img[i * bsize + k][j * bsize + l];   
                    
                //bsizeXbsize块DCT变换   
                dct(image, dct_coeft, dct_coef, bsize);//正变换   
                   
                //Output dct image   
                for (int k = 0; k < bsize; k++)   
                    for (int l = 0; l < bsize; l++)   
                        dct_image[i * bsize + k][j * bsize + l] = image[k][l];   
            }   
        }   
    }   
    else    
    {   
        for (int j = 0; j < iter_num; j++)   
        {   
            for (int i = 0; i < iter_num; i++)   
            {   
                //取bsizeXbsize图像块image[,]   
                for (int k = 0; k < bsize; k++)   
                    for (int l = 0; l < bsize; l++)   
                        image[k][l] = img[i * bsize + k][j * bsize + l];   
  
                //bsizeXbsize块IDCT变换   
                dct(image, dct_coef, dct_coeft, bsize);//逆变换   
                   
                //Output dct image   
                for (int k = 0; k < bsize; k++)   
                    for (int l = 0; l < bsize; l++)   
                        dct_image[i * bsize + k][j * bsize + l] = image[k][l];   
            }   
        }                   
    }   
    return dct_image;   
}   
  
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));   
}   
  
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);   
        }   
    }   
}  

 

实验效果如下:


0 0
原创粉丝点击