使用java编写DCT变换和反DCT变换

DCT变换、DCT反变换
matlab实现详细过程不使用函数实现

java实现二维数组DCT和反DCT变换,程序可直接执行

二维DCT变换其实是在一维DCT变换的基础上在做了一次DCT变换,其公式如下
在这里插入图片描述
由公式我们可以看出,上面只讨论了二维图像数据为方阵的情况,在实际应用中,如果不是方阵的数据一般都是补齐之后再做变换的,重构之后可以去掉补齐的部分,得到原始的图像信息,这个尝试一下,应该比较容易理解。
另外,由于DCT变换高度的对称性,在使用Matlab进行相关的运算时,我们可以使用更简单的矩阵处理方式
在这里插入图片描述



    public double [][] apllyDCT(int blocksize,  int block[][]) {


        double c = 0.0;
        double[][] A1 = new double[blocksize][blocksize];//A1代表变换矩阵
        double sizedouble=blocksize;
        for (int i=-1;i<blocksize-1;i++)
        {  if (i==-1)
            c=Math.sqrt(1/sizedouble);
        else
            c=Math.sqrt(2/sizedouble);
            for (int j=-1;j<blocksize-1;j++)
                A1[i+1][j+1]=c*Math.cos(Math.PI*(j+1+0.5)*(i+1)/sizedouble);
        }
//    for (int i=0;i<8;i++)
//    {
//        for (int j=0;j<8;j++)
//            System.out.println(A1[i][j]);
//        System.out.println('\n');
//    }
        double[][] A2 = new double[blocksize][blocksize];
        //二维数组转置
        for (int i=0;i<blocksize;i++)
        {
            for (int j=0;j<blocksize;j++)
                A2[j][i]=A1[i][j];
        }

        // 计算两个矩阵相乘
        double[][] AX = new double[blocksize][blocksize];
        for (int i = 0; i < blocksize; i++) {
            for (int j = 0; j < blocksize; j++) {
                for (int k = 0; k < blocksize; k++) {
                    AX[i][j] += A1[i][k] * block[k][j];
                }
            }
        }
        // 计算两个矩阵相乘
        double[][] AXA = new double[blocksize][blocksize];

        for (int i = 0; i < blocksize; i++) {
            for (int j = 0; j < blocksize; j++) {
                for (int k = 0; k < blocksize; k++) {
                    AXA[i][j] += AX[i][k] * A2[k][j];
                }
            }
        }



     return AXA;
    }


在图像的接收端,根据DCT变化的可逆性,我们可以通过DCT反变换恢复出原始的图像信息,其公式如下:在这里插入图片描述
同样的道理,我们利用之前的矩阵运算公司可以推导出DCT反变换相应的矩阵形式:
在这里插入图片描述



    public int [][] apllyIDCT(int blocksize,  double block[][]) {


        double c = 0.0;
        double[][] A1 = new double[blocksize][blocksize];//A1代表变换矩阵
        double sizedouble=blocksize;
        for (int i=-1;i<blocksize-1;i++)
        {  if (i==-1)
            c=Math.sqrt(1/sizedouble);
        else
            c=Math.sqrt(2/sizedouble);
            for (int j=-1;j<blocksize-1;j++)
                A1[i+1][j+1]=c*Math.cos(Math.PI*(j+1+0.5)*(i+1)/sizedouble);
        }
//    for (int i=0;i<8;i++)
//    {
//        for (int j=0;j<8;j++)
//            System.out.println(A1[i][j]);
//        System.out.println('\n');
//    }
        double[][] A2 = new double[blocksize][blocksize];
        //二维数组转置
        for (int i=0;i<blocksize;i++)
        {
            for (int j=0;j<blocksize;j++)
                A2[j][i]=A1[i][j];
        }

        // 计算两个矩阵相乘
        double[][] AX = new double[blocksize][blocksize];
        for (int i = 0; i < blocksize; i++) {
            for (int j = 0; j < blocksize; j++) {
                for (int k = 0; k < blocksize; k++) {
                    AX[i][j] += A2[i][k] * block[k][j];
                }
            }
        }
        // 计算两个矩阵相乘
        double[][] AXA = new double[blocksize][blocksize];
        int[][] AXA1 = new int[blocksize][blocksize];
        for (int i = 0; i < blocksize; i++) {
            for (int j = 0; j < blocksize; j++) {
                for (int k = 0; k < blocksize; k++) {
                    AXA[i][j] += AX[i][k] * A1[k][j];
                }
            }
        }
        for (int i = 0; i < blocksize; i++) {
            for (int j = 0; j < blocksize; j++) {
             AXA[i][j]=Math.round(AXA[i][j]);
                AXA1[i][j]=(new Double(AXA[i][j])).intValue();
            }
        }
        return AXA1;
    }


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值