Transformada de Coseno Discreta (Algoritmo y Programa)

Compresión de imagen: la imagen se almacena o transmite con un valor de píxel. Se puede comprimir reduciendo el valor que contiene cada píxel. La compresión de imágenes es básicamente de dos tipos: 

  1. Compresión sin pérdida: en este tipo de compresión, después de recuperar la imagen, se vuelve exactamente igual que antes de aplicar las técnicas de compresión y, por lo tanto, su calidad no se reduce. 
  2. Compresión con pérdida: en este tipo de compresión, después de la recuperación no podemos obtener exactamente los datos más antiguos y es por eso que la calidad de la imagen se reduce significativamente. Pero este tipo de compresión da como resultado una compresión muy alta de los datos de imagen y es muy útil para transmitir imágenes a través de la red.

La transformada de coseno discreta se usa en la compresión de imágenes con pérdida porque tiene una compactación de energía muy fuerte, es decir, su gran cantidad de información se almacena en un componente de muy baja frecuencia de una señal y el resto en otra frecuencia que tiene datos muy pequeños que se pueden almacenar usando muy menos número de bits (generalmente, como máximo 2 o 3 bits). 
Para realizar la Transformación DCT en una imagen, primero tenemos que obtener la información del archivo de imagen (valor de píxel en términos de enteros con un rango de 0 a 255) que dividimos en un bloque de array de 8 X 8 y luego aplicamos una transformación de coseno discreta en ese bloque de datos.

Después de aplicar la transformada de coseno discreta, veremos que más del 90% de sus datos estarán en un componente de frecuencia más bajo. Para simplificar, tomamos una array de tamaño 8 X 8 que tiene todos los valores como 255 (considerando que la imagen es completamente blanca) y vamos a realizar una transformada de coseno discreta 2-D para observar la salida.

Algoritmo: 

Supongamos que tenemos una variable 2-D llamada array de dimensión 8 X 8 que contiene información de la imagen y una variable 2-D llamada dct de la misma dimensión que contiene la información después de aplicar la transformada de coseno discreta. Entonces, tenemos la fórmula 
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) 
donde ci= 1/sqrt(m) if i=0 else ci= sqrt (2)/sqrt(m) y 
de manera similar, cj= 1/sqrt(n) if j=0 else cj= sqrt(2)/sqrt(n) 
y tenemos que aplicar esta fórmula a todo el valor, es decir, de i=0 a m-1 y j=0 a n-1
Aquí, sum(k=0 a m-1) denota la suma de valores de k=0 a k=m-1 
En este código, tanto m como n es igual a 8 y pise define como 3.142857.

Implementación:

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

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
Producción

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

Análisis de Complejidad:

  • Complejidad de tiempo : O((nm) 2 ), Usamos 4 bucles anidados en la función dctTransform() .
  • Espacio auxiliar : O(nm), Usamos espacio n*m para almacenar la transformada de coseno discreta.

Este artículo es una contribución de Aditya Kumar . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *