📜  离散余弦变换(算法和程序)

📅  最后修改于: 2021-04-29 01:41:06             🧑  作者: Mango

图像压缩:以像素值存储或传输图像。可以通过减小每个像素包含的值来对其进行压缩。图像压缩基本上有两种类型:
1.无损压缩:在这种类型的压缩中,恢复图像后与使用压缩技术之前的图像完全相同,因此其质量并未降低。
2.有损压缩:在这种类型的压缩中,恢复之后,我们将无法获得与旧数据完全相同的数据,这就是图像质量显着下降的原因。但是,这种类型的压缩会导致图像数据的非常高的压缩率,并且在通过网络传输图像时非常有用。
离散余弦变换用于有损图像压缩中,因为它具有非常强的能量压缩能力,即,其大量信息存储在信号的非常低的频率分量中,而其余的其他频率具有非常小的数据,可以通过使用很少的频率来存储位数(通常最多2或3位)。
要对图像执行DCT变换,首先我们必须获取图像文件信息(像素值,范围为0 – 255的整数),然后将其分成8 X 8矩阵块,然后对该块进行离散余弦变换。数据。
应用离散余弦变换后,我们将看到其超过90%的数据将包含在低频分量中。为简单起见,我们采用大小为8 X 8的矩阵,所有值均为255(认为图像是完全白色的),然后将对此进行2-D离散余弦变换以观察输出。

算法:让我们有一个二维变量名为8 x 8的矩阵,它包含图像信息,而一个二维变量dct具有相同的维数,在应用离散余弦变换之后,该二维变量包含信息。所以,我们有公式
dct [i] [j] = ci * cj(sum(k = 0至m-1)sum(l = 0至n-1)矩阵[k] [l] * cos((2 * k + 1)* i * pi / 2 * m)* cos((2 * l + 1)* j * pi / 2 * n)
如果i = 0则ci = 1 / sqrt(m),否则ci = sqrt(2)/ sqrt(m)和
类似地,如果j = 0则cj = 1 / sqrt(n),否则cj = sqrt(2)/ sqrt(n)
并且我们必须将此公式应用于所有值,即从i = 0到m-1和j = 0到n-1
在这里, sum(k = 0至m-1)表示从k = 0至k = m-1的值的总和。
在此代码中,m和n都等于8,并且pi定义为3.142857。

C++
// CPP program to perform discrete cosine transform
#include 
using namespace std;
#define pi 3.142857
const int m = 8, n = 8;
 
// Function to find discrete cosine transform and print it
int dctTransform(int matrix[][n])
{
    int i, j, k, l;
 
    // dct will store the discrete cosine transform
    float dct[m][n];
 
    float ci, cj, dct1, sum;
 
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
 
            // ci and cj depends on frequency as well as
            // number of row and columns of specified matrix
            if (i == 0)
                ci = 1 / sqrt(m);
            else
                ci = sqrt(2) / sqrt(m);
            if (j == 0)
                cj = 1 / sqrt(n);
            else
                cj = sqrt(2) / sqrt(n);
 
            // sum will temporarily store the sum of
            // cosine signals
            sum = 0;
            for (k = 0; k < m; k++) {
                for (l = 0; l < n; l++) {
                    dct1 = matrix[k][l] *
                           cos((2 * k + 1) * i * pi / (2 * m)) *
                           cos((2 * l + 1) * j * pi / (2 * n));
                    sum = sum + dct1;
                }
            }
            dct[i][j] = ci * cj * sum;
        }
    }
 
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            printf("%f\t", dct[i][j]);
        }
        printf("\n");
    }
}
 
// Driver code
int main()
{
    int matrix[m][n] = { { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 } };
    dctTransform(matrix);
    return 0;
}
 
//This code is contributed by SoumikMondal


Java
// Java program to perform discrete cosine transform
 
import java.util.*;
 
class GFG
{
    public static int n = 8,m = 8;
    public static double pi = 3.142857;
     
    // Function to find discrete cosine transform and print it
    static strictfp void dctTransform(int matrix[][])
    {
        int i, j, k, l;
  
        // dct will store the discrete cosine transform
        double[][] dct = new double[m][n];
  
        double ci, cj, dct1, sum;
  
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
            {
                // ci and cj depends on frequency as well as
                // number of row and columns of specified matrix
                if (i == 0)
                    ci = 1 / Math.sqrt(m);
                else
                    ci = Math.sqrt(2) / Math.sqrt(m);
                     
                if (j == 0)
                    cj = 1 / Math.sqrt(n);
                else
                    cj = Math.sqrt(2) / Math.sqrt(n);
  
                // sum will temporarily store the sum of
                // cosine signals
                sum = 0;
                for (k = 0; k < m; k++)
                {
                    for (l = 0; l < n; l++)
                    {
                        dct1 = matrix[k][l] *
                               Math.cos((2 * k + 1) * i * pi / (2 * m)) *
                               Math.cos((2 * l + 1) * j * pi / (2 * n));
                        sum = sum + dct1;
                    }
                }
                dct[i][j] = ci * cj * sum;
            }
        }
  
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
                System.out.printf("%f\t", dct[i][j]);
            System.out.println();
        }
    }
     
    // driver program
    public static void main (String[] args)
    {
        int matrix[][] = { { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 },
                         { 255, 255, 255, 255, 255, 255, 255, 255 } };
        dctTransform(matrix);
    }
}
 
// Contributed by Pramod Kumar


C#
// C# program to perform discrete cosine transform
using System;
 
class GFG
{
   
  // Function to find discrete cosine transform and print it
  public static void dctTransform(int[,] matrix, int m, int n)
  {
    double pi = 3.142857;      
    int i, j, k, l;
 
    // dct will store the discrete cosine transform
    double[,] dct = new double[m, n];
    double ci, cj, dct1, sum;
    for (i = 0; i < m; i++)
    {
      for (j = 0; j < n; j++)
      {
 
        // ci and cj depends on frequency as well as
        // number of row and columns of specified matrix
        if (i == 0)
          ci = 1 / Math.Sqrt(m);
        else
          ci = Math.Sqrt(2) / Math.Sqrt(m);
        if (j == 0)
          cj = 1 / Math.Sqrt(n);
        else
          cj = Math.Sqrt(2) /Math.Sqrt(n);
 
        // sum will temporarily store the sum of
        // cosine signals
        sum = 0;
        for (k = 0; k < m; k++)
        {
          for (l = 0; l < n; l++)
          {
            dct1 = matrix[k, l] *
              Math.Cos((2 * k + 1) * i * pi / (2 * m)) *
              Math.Cos((2 * l + 1) * j * pi / (2 * n));
            sum = sum + dct1;
          }
        }
        dct[i,j] = ci * cj * sum;
      }
    }
 
    for (i = 0; i < m; i++)
    {
      for (j = 0; j < n; j++)
      {
        Console.Write(dct[i,j]);
      }
      Console.WriteLine();
    }
  }
   
  // Driver code
  static void Main()
  {
    const int m = 8, n = 8;
    int[,] matrix = new int[m, n] {
      { 255, 255, 255, 255, 255, 255, 255, 255 },
      { 255, 255, 255, 255, 255, 255, 255, 255 },
      { 255, 255, 255, 255, 255, 255, 255, 255 },
      { 255, 255, 255, 255, 255, 255, 255, 255 },
      { 255, 255, 255, 255, 255, 255, 255, 255 },
      { 255, 255, 255, 255, 255, 255, 255, 255 },
      { 255, 255, 255, 255, 255, 255, 255, 255 },
      { 255, 255, 255, 255, 255, 255, 255, 255 }
    };
    dctTransform(matrix, m, n);
  }
}
 
// This code is contributed by SoumikMondal


输出:

2039.999878    -1.168211    1.190998    -1.230618    1.289227    -1.370580    1.480267    -1.626942    
-1.167731       0.000664    -0.000694    0.000698    -0.000748    0.000774    -0.000837    0.000920    
1.191004       -0.000694    0.000710    -0.000710    0.000751    -0.000801    0.000864    -0.000950    
-1.230645       0.000687    -0.000721    0.000744    -0.000771    0.000837    -0.000891    0.000975    
1.289146       -0.000751    0.000740    -0.000767    0.000824    -0.000864    0.000946    -0.001026    
-1.370624       0.000744    -0.000820    0.000834    -0.000858    0.000898    -0.000998    0.001093    
1.480278       -0.000856    0.000870    -0.000895    0.000944    -0.001000    0.001080    -0.001177    
-1.626932       0.000933    -0.000940    0.000975    -0.001024    0.001089    -0.001175    0.001298