MATLAB DCT变换原理和源码

图像处理中常用的正交变换除了傅里叶变换外,还有其他一些有用的正交变换,其中离散余弦就是一种。离散余弦变换表示为DCT( Discrete Cosine Transformation),常用于图像处理和图像识别等。

一维离散余弦变换

正变换

                                   (1)

                            (2)

式中F(u)是第u个余弦变换系数,u是广义频率变量,u=1,2,3......N-1; f(x)是时域N点序列, x=0,1,2......N-1

反变换

  (3)

显然,式(1)式(2)和式(3)构成了一维离散余弦变换对。

二维离散余弦变换

正变换

  (4)

式(4)是正变换公式。其中f(x,y)是空间域二维向量之元素, x,y=0,1,2,......N-1;F(u,v)是变换系数阵列之元素。式中表示的阵列为N×N

反变换

 (5)

式中的符号意义同正变换式一样。式(4)和式(5)是离散余弦变换的解析式定义。

矩阵表示法

更为简洁的定义方法是采用矩阵式定义。根据以上公式定义可知,离散余弦变换的系数矩阵可以写成如下:



如果令N=4,那么由一维解析式定义可得如下展开式。


写成矩阵式


若定义F(u)为变换矩阵,A为变换系数矩阵,f(x)为时域数据矩阵,则一维离散余弦变换的矩阵定义式可写成如下形式

[F(u)]=[A][f(x)]                       6

同理,可得到反变换展开式


写成矩阵式

[f(x)]=[A]T[F(u)]                      (7

二维离散余弦变换也可以写成矩阵式:

[F(u,v)]=[A][f(x,y)][A]T            (8

[f(x,y)]=[A]T[F(u,v)][A]                     

式中[f(x,y)]是空间数据阵列,A是变换系数阵列,[F(u,v)]是变换矩阵,[A]T是[A]的转置。

对二维图像进行离散余弦变换

由以上对二维离散余弦变换的定义及公式(7)可知,求二维图像的离散余弦变换要进行以下步骤:

1.获得图像的二维数据矩阵f(x,y)

2.求离散余弦变换的系数矩阵[A];

3.求系数矩阵对应的转置矩阵[A]T;

4.根据公式(7[F(u,v)]=[A][f(x,y)][A]T 计算离散余弦变换;

源代码:

[java]  view plain  copy
  1. package cn.edu.jxau.image;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4.   
  5. /** 
  6.  * 图像的变换 
  7.  * @author luoweifu 
  8.  * 
  9.  */  
  10. public class Transformation {  
  11.     /** 
  12.      * 要进行DCT变换的图片的宽或高 
  13.      */  
  14.     public static final int N = 256;  
  15.       
  16.     /** 
  17.      * 傅里叶变换 
  18.      * @return 
  19.      */  
  20.     public int[] FFT() {  
  21.           
  22.         return null;  
  23.     }  
  24.       
  25.     /** 
  26.      * 离散余弦变换 
  27.      * @param pix 原图像的数据矩阵 
  28.      * @param n 原图像(n*n)的高或宽 
  29.      * @return 变换后的矩阵数组 
  30.      */  
  31.     public int[] DCT(int[] pix, int n) {          
  32.         double[][] iMatrix = new double[n][n];   
  33.         for(int i=0; i<n; i++) {  
  34.             for(int j=0; j<n; j++) {  
  35.                 iMatrix[i][j] = (double)(pix[i*n + j]);  
  36.             }  
  37.         }  
  38.         double[][] quotient = coefficient(n);   //求系数矩阵  
  39.         double[][] quotientT = transposingMatrix(quotient, n);  //转置系数矩阵  
  40.           
  41.         double[][] temp = new double[n][n];  
  42.         temp = matrixMultiply(quotient, iMatrix, n);  
  43.         iMatrix =  matrixMultiply(temp, quotientT, n);  
  44.           
  45.         int newpix[] = new int[n*n];  
  46.         for(int i=0; i<n; i++) {  
  47.             for(int j=0; j<n; j++) {  
  48.                 newpix[i*n + j] = (int)iMatrix[i][j];  
  49.             }  
  50.         }  
  51.         return newpix;  
  52.     }  
  53.     /** 
  54.      * 矩阵转置 
  55.      * @param matrix 原矩阵 
  56.      * @param n 矩阵(n*n)的高或宽 
  57.      * @return 转置后的矩阵 
  58.      */  
  59.     private double[][]  transposingMatrix(double[][] matrix, int n) {  
  60.         double nMatrix[][] = new double[n][n];  
  61.         for(int i=0; i<n; i++) {  
  62.             for(int j=0; j<n; j++) {  
  63.                 nMatrix[i][j] = matrix[j][i];  
  64.             }  
  65.         }  
  66.         return nMatrix;  
  67.     }  
  68.     /** 
  69.      * 求离散余弦变换的系数矩阵 
  70.      * @param n n*n矩阵的大小 
  71.      * @return 系数矩阵 
  72.      */  
  73.     private double[][] coefficient(int n) {  
  74.         double[][] coeff = new double[n][n];  
  75.         double sqrt = 1.0/Math.sqrt(n);  
  76.         for(int i=0; i<n; i++) {  
  77.             coeff[0][i] = sqrt;  
  78.         }  
  79.         for(int i=1; i<n; i++) {  
  80.             for(int j=0; j<n; j++) {  
  81.                 coeff[i][j] = Math.sqrt(2.0/n) * Math.cos(i*Math.PI*(j+0.5)/(double)n);  
  82.             }  
  83.         }  
  84.         return coeff;  
  85.     }  
  86.     /** 
  87.      * 矩阵相乘 
  88.      * @param A 矩阵A 
  89.      * @param B 矩阵B 
  90.      * @param n 矩阵的大小n*n 
  91.      * @return 结果矩阵 
  92.      */  
  93.     private double[][] matrixMultiply(double[][] A, double[][] B, int n) {  
  94.         double nMatrix[][] = new double[n][n];  
  95.         double t = 0.0;  
  96.         for(int i=0; i<n; i++) {  
  97.             for(int j=0; j<n; j++) {  
  98.                 t = 0;  
  99.                 for(int k=0; k<n; k++) {  
  100.                     t += A[i][k]*B[k][j];  
  101.                 }  
  102.                 nMatrix[i][j] = t;          }  
  103.         }  
  104.         return nMatrix;  
  105.     }  
  106.       
  107. }  

  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值