Bonjour à tous,
J’implémente la compression JPEG expliquée dans le tutoriel d’@Antho : https://zestedesavoir.com/articles/1532/la-compression-jpeg/.
L’auteur donne la définition d’une fréquence :
$DCT_{u,v}= \frac 14 \sum_{x=0}^{7}\sum_{y=0}^{7}Pixels_{x,y} \cos{\left[ \dfrac{(2x+1)u\pi}{16} \right]} \cos{\left[ \dfrac{(2y+1)v\pi} {16} \right]}$
Avec $u$ et $v$ les coordonnées de la fréquence que l’on veut calculer dans la matrice des fréquences et $x$ et $y$, les coordonnées de la valeur YUV que l’on souhaite convertir en fréquence dans la matrice des valeurs YUV. Par ailleurs, $DCT_{u,v}$ correspond bien sûr à la case de la matrice des fréquences aux coordonnées indicées, et $Pixels_{x,y}$ correspond àla case de la matrice des valeurs YUV aux coordonnées indicées.
Je cherche à utiliser cette définition pour convertir mes valeurs de luminance en fréquences, et c’est là que j’ai un problème.
Quel est le résultat actuel de mon implémentation ?
Quel est le problème ?
Les valeurs que j’ai calculées et qu’on peut voir dans la matrice "DCTed luminance matrix" ne sont pas les mêmes que celles fournies par Anto59290.
Valeurs que j’aurais dû trouver
Note : Les valeurs de luminance que j’utilise sont les mêmes que celles employées par l’auteur. Vous pouvez donc les trouver dans mon screenshot (cf. "Luminance matrix").
Le tutoriel indique ces valeurs de luminances converties en fréquences (méthode DCT) :
Code source d’implémentation (C++) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { float b = 0.0f; for (int x = 0; x < 8; x++) { float a = 0.0f; for (int y = 0; y < 8; y++) { a += luminance_matrix[x][y] * cos(((2 * x + 1) * u * 3.141) / 16) * cos(((2 * y + 1) * v * 3.141) / 16); } b += a; } dct_matrix[u][v] = (float)1 / 4 * b; } } |
Voilà voilà… est-ce moi qui ai mal compris comment implémenter cette conversion ou le problème vient-il de la formule écrite par Antho ?
Edit (important) : sujet résolu
La formule du tuto était incorrecte (formule correcte, cf. Wikipédia : )
Implémentation (elle fonctionne)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { float b = 0.0f; for (int x = 0; x < 8; x++) { float a = 0.0f; for (int y = 0; y < 8; y++) { a += luminance_matrix[x][y] * cos(((2 * x + 1) * u * 3.1415926536) / 16) * cos(((2 * y + 1) * v * 3.1415926536) / 16); } b += a; } if (u == 0) { if (v == 0) { dct_matrix[u][v] = (float)1 / 4 * 0.7071067812 * 0.7071067812 * b; } else if (v > 0) { dct_matrix[u][v] = (float)1 / 4 * 0.7071067812 * b; } } else if (u > 0) { if (v == 0) { dct_matrix[u][v] = (float)1 / 4 * 0.7071067812 * b; } else if (v > 0) { dct_matrix[u][v] = (float)1 / 4 * b; } } } } |