Open In App

Discrete Cosine Transform (Algorithm and Program)

Last Updated : 05 Aug, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Image Compression : Image is stored or transmitted with having pixel value. It can be compressed by reducing the value its every pixel contains. Image compression is basically of two types : 

  1. Lossless compression : In this type of compression, after recovering image is exactly become same as that was before applying compression techniques and so, its quality didn’t gets reduced. 
  2. Lossy compression : In this type of compression, after recovering we can’t get exactly as older data and that’s why the quality of image gets significantly reduced. But this type of compression results in very high compression of image data and is very useful in transmitting image over network.

Discrete Cosine Transform is used in lossy image compression because it has very strong energy compaction, i.e., its large amount of information is stored in very low frequency component of a signal and rest other frequency having very small data which can be stored by using very less number of bits (usually, at most 2 or 3 bit). 
To perform DCT Transformation on an image, first we have to fetch image file information (pixel value in term of integer having range 0 – 255) which we divides in block of 8 X 8 matrix and then we apply discrete cosine transform on that block of data.

After applying discrete cosine transform, we will see that its more than 90% data will be in lower frequency component. For simplicity, we took a matrix of size 8 X 8 having all value as 255 (considering image to be completely white) and we are going to perform 2-D discrete cosine transform on that to observe the output.

Algorithm : 

Let we are having a 2-D variable named matrix of dimension 8 X 8 which contains image information and a 2-D variable named dct of same dimension which contain the information after applying discrete cosine transform. So, we have the formula 
dct[i][j] = ci * cj (sum(k=0 to m-1) sum(l=0 to n-1) matrix[k][l] * cos((2*k+1) *i*pi/2*m) * cos((2*l+1) *j*pi/2*n) 
where ci= 1/sqrt(m) if i=0 else ci= sqrt(2)/sqrt(m) and 
similarly, cj= 1/sqrt(n) if j=0 else cj= sqrt(2)/sqrt(n) 
and we have to apply this formula to all the value, i.e., from i=0 to m-1 and j=0 to n-1
Here, sum(k=0 to m-1) denotes summation of values from k=0 to k=m-1. 
In this code, both m and n is equal to 8 and pi is defined as 3.142857.

Implementation:

C++




// CPP program to perform discrete cosine transform
#include <bits/stdc++.h>
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


Python3




# Python3 program to perform discrete cosine transform
import math
 
pi = 3.142857
m = 8
n = 8
 
# Function to find discrete cosine transform and print it
def dctTransform(matrix):
 
    # dct will store the discrete cosine transform
    dct = []
    for i in range(m):
        dct.append([None for _ in range(n)])
 
    for i in range(m):
        for j in range(n):
 
            # ci and cj depends on frequency as well as
            # number of row and columns of specified matrix
            if (i == 0):
                ci = 1 / (m ** 0.5)
            else:
                ci = (2 / m) ** 0.5
            if (j == 0):
                cj = 1 / (n ** 0.5)
            else:
                cj = (2 / n) ** 0.5
 
            # sum will temporarily store the sum of
            # cosine signals
            sum = 0
            for k in range(m):
                for l in range(n):
 
                    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 in range(m):
        for j in range(n):
            print(dct[i][j], end="\t")
        print()
 
# Driver code
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)
 
# This code is contributed by phasing17


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


Javascript




// JavaScript program to perform discrete cosine transform
 
let pi = 3.142857
let m = 8, n = 8;
 
// Function to find discrete cosine transform and print it
function dctTransform(matrix)
{
    let i, j, k, l;
 
    // dct will store the discrete cosine transform
    let dct = new Array();
    for (i = 0; i < m; i++)
        dct.push(new Array(n));
 
    let 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++) {
            process.stdout.write(dct[i][j] + "\t");
        }
        console.log();
    }
}
 
// Driver code
let 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);
 
 
//This code is contributed by phasing17


Output

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

Complexity Analysis:

  • Time Complexity: O((nm)2),  We used 4 nested loops in the dctTransform() function.
  • Auxiliary Space: O(nm),  We used n*m space for storing the discrete cosine transform.

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads