From db31cde05cbf52308f5a19da5d66916e5023469b Mon Sep 17 00:00:00 2001 From: "iliya.saroukha" <iliya.saroukhanian@etu.hesge.ch> Date: Fri, 18 Apr 2025 14:24:48 +0200 Subject: [PATCH] feat: finished report about dct --- report/report.qmd | 109 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 99 insertions(+), 10 deletions(-) diff --git a/report/report.qmd b/report/report.qmd index 45b5420..caf5683 100644 --- a/report/report.qmd +++ b/report/report.qmd @@ -30,16 +30,19 @@ la suivante : ## Implémentation Initialement, afin d'appliquer la DCT à l'image choisie, il est nécessaire de -calculer la matrice $\mathbf{C}$ des coefficients de la DCT. Celle-ci sera en fait une -matrice de dimension 8x8 du fait que nous allons travailler sur la même taille -de bloc de l'image. La formule de la matrice $\mathbf{C}$ est la suivante : +calculer la matrice $\mathbf{C}$ des coefficients de la DCT. Celle-ci sera en +fait une matrice de dimension 8x8 du fait que nous allons travailler sur la +même taille de bloc de l'image. La formule de la matrice $\mathbf{C}$ est la +suivante : $$ \mathbf{C}_{ij} = \begin{cases} \frac{1}{\sqrt{N}}, & \text{si $i$ = 0}\\ \sqrt{\frac{2}{N}}\cos{\frac{(2j + 1)i\pi}{2N}}, & \text{sinon} \end{cases} -$$ +$$ {#eq-cos-coeff-mat} + +\newpage ```python def cos_mat(n: int) -> Img: @@ -63,8 +66,8 @@ la transposée de $\mathbf{C}^{T}$ pour obtenir le résultat final sur le bloc sélectionné. La formule de ce calcul est la suivante : $$ -\text{DCT} = \mathbf{C}\mathbf{M}\mathbf{C}^{T} -$$ +\mathbf{M}_{\text{DCT}} = \mathbf{C}\mathbf{M}\mathbf{C}^{T} +$$ {#eq-dct} ```python def dct(padded_img: Img, kernel_size: int) -> Img: @@ -103,15 +106,15 @@ ci-dessous : {width="70%"} -## Reconstitution de l'image +## Reconstitution de l'image {#sec-reconst-img} Afin de retrouver l'image initiale mais cette fois-ci compressée à travers l'application de la DCT, il est nécessaire d'appliquer la DCT inverse sur l'image de la DCT. La formule de celle-ci est ci-dessous : $$ -\text{IDCT} = \mathbf{C}^{-1}\mathbf{M}(\mathbf{C}^{-1})^{T} -$$ +\text{IDCT} = \mathbf{C}^{-1}\mathbf{M}_{\text{DCT}}(\mathbf{C}^{-1})^{T} +$$ {#eq-idct} ```python @@ -137,7 +140,93 @@ de l'image initiale est présentée ci-dessous : {width="70%"} -### Matrice des coefficients de la DCT pour un bloc 8x8 +## Quantification + +Dans l'optique d'amplifier l'effet de compression, nous allons quantifier le +résultat de la DCT de l'image originale afin d'atteindre cet objectif. Pour ce +faire il nous est nécessaire de calculer en premier lieu la matrice de +quantification en fonction d'un facteur de qualité $q$ fourni. Plus ce facteur est +élevé, plus la dégradation de la qualité de l'image sera grande. Du fait que +nous travaillons toujours sur des blocs 8x8, la matrice de quantification +$\mathbf{Q}$ possédera donc ces dimensions. La valeur de chaque entrée de cette +matrice est calculée de la manière suivante : + +$$ +\mathbf{Q}_{ij} = 1 + q(i + j + 1) +$$ {#eq-quant-mat} + +L'implémentation de la fonction `quantized` dont le but est de créer la matrice +$\mathbf{Q}$ est représentée ci-dessous : + +```python +def quantized(kernel_size: int, quality: int) -> Img: + quant = np.zeros((kernel_size, kernel_size)) + + for i in range(0, quant.shape[0]): + for j in range(0, quant.shape[1]): + quant[i, j] = 1 + (i + j + 1) * quality + + return quant +``` + +Ayant obtenu cette matrice, il est à présent possible quantifier la DCT de +l'image obtenue au préalable. Pour ce faire, nous allons à nouveau séléctionner +des sous-sections de taille 8x8 de la DCT et allons diviser ce bloc par la +matrice de quantification $\mathbf{Q}$. Du fait que nous travaillons avec des +tableaux `numpy`, il nous est possible de diviser un tableau par un autre du +fait que l'opérateur **`/`** est surchargé. En l'occurrence, celui-ci +effectuera une division entrée par entrée entre les deux matrices à partir du +moment qu'elles possèdent les mêmes dimensions. Les résultats de division seront +arrondis à l'entier le plus proche à travers la fonction `np.round`. La matrice +résultante $\mathbf{Q}_{\text{DCT}}$ de cette opération encodera la dégradation +supplémentaire ajoutée à la DCT. + +```python +def quantize_dct(dct_img: Img, kernel_size: int, quality: int) -> Img: + final_mat = dct_img.copy() + quant = quantized(kernel_size, quality) + + for i in range(0, dct_img.shape[0], kernel_size): + for j in range(0, dct_img.shape[1], kernel_size): + final_mat[i:i+kernel_size, j:j+kernel_size] = np.round( + dct_img[i:i+kernel_size, j:j+kernel_size] / quant) + + return final_mat +``` + +{width="70%"} + +Afin de reconstituer l'image à partir de la DCT quantifiée obtenue, il est +nécessaire d'appliquer le même algorithme que celui explicitée dans la +@sec-reconst-img. La seule chose qui va changer dans le calcul de la IDCT est +évidemment la matrice fournie. Nous aurons toujours besoin de l'inverse de +la matrice des coefficients $\mathbf{C}$ ainsi que de sa transposée cependant +le calcul se fera avec la matrice de la DCT quantifiée $\mathbf{Q}_{\text{DCT}}$ + +$$ +\text{IDCT} = \mathbf{C}^{-1}\mathbf{Q}_{\text{DCT}}(\mathbf{C}^{-1})^{T} +$$ {#eq-quant-idct} + +L'image ci-dessous illustre bien l'effet de la dégradation introduit par la +quantification de la DCT. En l'occurrence, la valeur pour le facteur $q$ choisi +est de 20. + +{width="70%"} + +## Résumé du travail + +Ce travail pratique nous a permis de mettre en œuvre les connaissances acquises +en terme de compression d'image et de l'utilisation de la transformée discrète +en cosinus afin d'atteindre cet objectif. L'implémentation effectuée permet +à l'utilisateur du programme de spécifier sur la ligne de commande le chemin +vers une image. + +```bash +python3 dct.py ~/Downloads/forest.png +``` +Le programme effectuera les diverses transformations nécessaires et affichera +le résultat de la DCT, de son inverse, de la DCT quantifiée et finalement de +l'inverse quantifiée. # Huffman Adaptatif -- GitLab