cerhu > comp.* > comp.algorithmes

Etienne (08/12/2010, 13h23)
salut.
J'expérimente actuellement la compression JPEG.

J'ai codé pour tester une DCT et une iDCT.
Sauf que voila, l'exécution successive des deux algo ne me redonne pas
(et de loin) la matrice originale.

Voila le source (en PHP) qui est assez simple finalement.

$pixel = array(
array(139, 144, 149, 153, 155, 155, 155, 155),
array(144, 151, 153, 156, 159, 156, 156, 156),
array(150, 155, 160, 163, 158, 156, 156, 156),
array(159, 161, 162, 160, 160, 159, 159, 159),
array(159, 160, 161, 162, 162, 155, 155, 155),
array(161, 161, 161, 161, 160, 157, 157, 157),
array(162, 162, 161, 163, 162, 157, 157, 157),
array(162, 162, 161, 161, 163, 158, 158, 158));

/* DCT */

for ($i = 0 ; $i < 8 ; $i++)
for ($j = 0 ; $j < 8 ; $j++)
{
$s = 0.0;
for ($x = 0 ; $x < 8; $x++)
for ($y = 0 ; $y < 8; $y++)
{
if (($i == 0) && ($j == 0))
$c = 0.25 / (sqrt(2) * sqrt(2));
else if (($i == 0) || ($j == 0))
$c = 0.25 / sqrt(2);
else if (($i == 0) || ($j == 0))
$c = 0.25;

$coef = $c * cos(((2*$x+1)*$i*M_PI) / 16) *
cos(((2*$y+1)*$j*M_PI) / 16);
$value = $coef * $pixel[$x][$y];
$s += $value;
}
$dct[$i][$j] = $s;
}

/* iDCT */

for ($i = 0 ; $i < 8 ; $i++)
for ($j = 0 ; $j < 8 ; $j++)
{
$s = 0.0;
for ($x = 0 ; $x < 8; $x++)
for ($y = 0 ; $y < 8; $y++)
{
if (($x == 0) && ($y == 0))
$c = 0.25 / (sqrt(2) * sqrt(2));
else if (($x == 0) || ($y == 0))
$c = 0.25 / sqrt(2);
else if (($x == 0) || ($y == 0))
$c = 0.25;

$coef = $c * cos(((2*$x+1)*$i*M_PI) / 16) *
cos(((2*$y+1)*$j*M_PI) / 16);
$value = $coef * $dct[$x][$y];
$s += $value;
}
$idct[$i][$j] = $s;
}

J'ai utilisé la table exemple fournie par sur
[..]

La matrice de départ etait
139 144 149 153 155 155 155 155
144 151 153 156 159 156 156 156
150 155 160 163 158 156 156 156
159 161 162 160 160 159 159 159
159 160 161 162 162 155 155 155
161 161 161 161 160 157 157 157
162 162 161 163 162 157 157 157
162 162 161 161 163 158 158 158

Le résultat obtenu est
142 142 139 129 110 85 58 30
143 144 140 127 111 85 58 30
140 141 136 125 104 78 54 28
135 133 126 113 95 73 50 26
116 113 107 95 81 59 41 21
91 89 84 75 63 48 33 17
64 63 58 52 45 33 23 12
33 32 30 26 23 17 12 6

Alors évidement:
- je n'ai rien arrondi (tous les calcul en float)
- je n'ai pas utilisé de quantization.

Bref, j'ai juste appliqué le DCT et l'iDCT et je suis très surpris des
écart obtenus !!!

Les pertes sont-elles dues aux flottants 32 bits?
Ou dois chercher un bug dans mon iDCT (encore que bon j'ai déjà pas mal
cherché)
PS: le problème ne dois pas venir de la DCT sinon je ne trouverai pas
des valeurs identiques à celles présente sur Wikipedia.

Etienne
Etienne (08/12/2010, 13h30)
Le 08/12/2010 12:25, Etienne a écrit :

Oups.
Je viens juste de me rendre compte de l'écart énnnnnorme entre la
matrice originale et celle de destination.

J'ai du faire une modif dans mon iDCT, car si les écarts était grand, il
ne l'était pas autant.

Faut que je remette mon iDCT originale est que je repost !!!

Désolé pour la boulette.
Etienne
[..]
Etienne (08/12/2010, 14h52)
Le 08/12/2010 12:31, Etienne a écrit :
> Le 08/12/2010 12:25, Etienne a écrit :
> Oups.


Ok voila la formule de l'iDCT

for ($i = 0 ; $i < 8; $i++)
for ($j = 0 ; $j < 8; $j++)
{
$s = 0.0;
for ($u = 0 ; $u < 8 ; $u++)
for ($v = 0 ; $v < 8 ; $v++)
{
if (($u == 0) && ($v == 0))
$c = 0.25 / (sqrt(2) * sqrt(2));
else if (($u == 0) || ($v == 0))
$c = 0.25 / sqrt(2);
else if (($u == 0) || ($v == 0))
$c = 0.25;

$coef = $c * cos(((2*$i+1)*$u*M_PI) / 16) *
cos(((2*$j+1)*$v*M_PI) / 16);
$value = $coef * $dct[$u][$v];
$s += $value;
}
$idct[$i][$j] = $s;
}

La matrice de départ était
139 144 149 153 155 155 155 155
144 151 153 156 159 156 156 156
150 155 160 163 158 156 156 156
159 161 162 160 160 159 159 159
159 160 161 162 162 155 155 155
161 161 161 161 160 157 157 157
162 162 161 163 162 157 157 157
162 162 161 161 163 158 158 158

Le résultat obtenu est
143 147 150 153 154 152 152 152
147 152 154 156 158 155 155 155
152 156 159 161 159 156 156 156
158 160 161 161 161 159 159 159
157 159 160 162 162 156 156 156
159 160 161 161 161 158 158 158
160 161 161 163 162 158 158 158
160 161 161 162 163 159 159 159

Donc des ecart quand meme assez important...
Pascal J. Bourguignon (08/12/2010, 16h16)
Etienne <etienne> writes:

[..]
> }
> $idct[$i][$j] = $s;
> }


Non, elle est encore fausse...

> Donc des ecart quand meme assez important...


Pas étonnant.
WebShaker (08/12/2010, 19h52)
Le 08/12/2010 15:17, Pascal J. Bourguignon a écrit :
> Non, elle est encore fausse...
>> Donc des ecart quand meme assez important...

> Pas étonnant.


Comment ca elle est encore fausse.

J'ai pris la formule ici

[..]

A l'origine j'avais mis en place l'algorithme de chen
que j'avais pris ici

[..]

Et c'est à cause des erreurs que j'ai codé l'idct brut de fonderie.
l'algorithme de chen et mon idct donne quasiment le même résultat.

Ce qui me laissait à penser que l'idct était juste !!!

Non ???

Etienne
Serge Paccalin (08/12/2010, 20h31)
Le Wed, 08 Dec 2010 13:53:43 +0100, Etienne a écrit
(dans <news:4cff7f37$0$30332$426a34cc>, posté
dans fr.comp.algorithmes) :

> if (($u == 0) && ($v == 0))
> $c = 0.25 / (sqrt(2) * sqrt(2));
> else if (($u == 0) || ($v == 0))
> $c = 0.25 / sqrt(2);
> else if (($u == 0) || ($v == 0))
> $c = 0.25;


Il y a un lézard dans les conditions?
WebShaker (08/12/2010, 23h05)
Le 08/12/2010 19:31, Serge Paccalin a écrit :
> Il y a un lézard dans les conditions?


Damned !!!
C'était donc les deux fonctions qui étaient fausses !
Ca marche nettement mieux a présent.

Merci !!!!!

Etienne
Discussions similaires
Perte d'information Import txt

Perte d'information dans un csv

Perte information a chaque redemarage

Iptables, --limit et perte d'information


Fuseau horaire GMT +2. Il est actuellement 16h04. | Privacy Policy