3000回くらい回していたのだが、確認してみると18回目で既に前回と同一の画像が出力されていた。このように、繰り返し保存による劣化は早々に止まることが分かる。今回は1種類に収束したが、以前試した時は3種類のローテーションになったこともあった。見て分かる(分からない)とおり、1回目と17回目で差はほとんど無い。念のため差分をとってみよう。見えないので64倍に強調したものも置いておく。そもそも非可逆圧縮の原理は、元データを少々変えて「圧縮しやすいデータ」を作り、それを可逆圧縮するものと解釈できる。よって一度非可逆圧縮したデータを展開したデータは、既に「圧縮しやすいデータ」になっているため、同じ設定で圧縮すれば完全に可逆圧縮になってもおかしくない。17回まで劣化が続くことの方が不思議といえる。JPEGの圧縮の根幹である離散コサイン変換(DCT)は本来は可逆なのだが、実際には有限の精度で計算するために丸め誤差が発生する。これがJPEG再圧縮が不可逆な原因だと思う。JPEGの仕様はあまり厳密でないようで、エンコードでは演算の精度をソフトの自由で選べたり、デコードもソフトによって結果が違ったりする。これも一因かもしれない。(2/11追記)RGB→YUVの変換も丸め誤差が発生するので一因かもしれない。次にパラメータを少し変えてみる。今度は劣化が103回目まで続く。劣化の度合いも目に見えて分かる。色が褪せていて、特に赤が大幅にくすんでしまっている。見にくいので4倍に強調しておこう。闇夜に光る眼のようで可愛い。何を変えたかというと、カラーサブサンプリングだ。カラーサブサンプリングは、クロマサブサンプリングや色成分間引きと呼ばれたり、単にサンプリングやサンプリング比という名の設定項目で設定したりする。名前が定まっておらず面倒な概念だ。先の17回で劣化が止まったものは、カラーサブサンプリングがOff、別の言い方をするとサンプリングが1x1や4:4:4と呼ばれるものだ。この設定では輝度成分と色成分を元の解像度のまま処理する。この時、画像は8×8のブロックごとに処理され、隣のブロックとの間で影響を及ぼすことはない。103回の方は、カラーサブサンプリングがOn、サンプリングが2x2や4:2:0と呼ばれる設定であり、輝度成分は元解像度で、色成分は縦横1/2に縮小してから処理をする。この縮小で単純に2×2ピクセルを平均するのであれば16×16のブロック内に影響が留まるだろうが、どうもそうではなく線形補間か何かをされているようで、ドットの色が16×16pxの境界を越えてにじむ現象が見られる。これにより隣のブロックの色が圧縮に影響し、次回は隣の隣のブロックにまで波及し、と際限なく影響を与え合う。厳密なことは分からないがこれが劣化が長く続く理由ではないかと思う。劣化が蓄積するというのは、カラーサブサンプリングOnの設定においてはある程度正しい。それにしても際限なく劣化するということはないし、JPEGが全てそのように劣化するわけでもないことは上で示したとおりだ。ひとつ、冒頭の例のように完全なノイズにまで際限なく劣化させるにはどうすればよいだろう。劣化しそうな方法をいろいろ試してみた。圧縮率を毎回変えたら量子化の閾値が変わることで劣化が続くのではないかと考えたのだが、駄目であった。1万回繰り返してもほぼ劣化が見えなかった。(同じ画像が続くことは無かったので何パターンかのローテーションになっていたようだ)次に90度回転を試したがこれも同様であった。今回使ったJPEGの量子化行列は縦と横で対称でないのでそれによるゆらぎを期待したのだが...。そこで毎回画像の位置をずらしてみることにした。7回右下へ1pxずらしたあと、1回左上に7pxずらして戻すの繰り返し。これは見事に成功、これでできたのが冒頭の画像だ。これが上手くいくかは、正確なことは分からないが、特定のドットに注目するとそのドットは8×8のブロック内で位置が毎回変わるようになっており、これで誤差が波及し続けるのが一因だろう。サンプリング2x2の時は止まってしまったのでそれ以外に何かあるのだろうが、よく分からない。何か誤差が発振するような機構があるのだろうか...。90度回転も、画像サイズが8×8の倍数でない場合はずらすのと同じことになる。以上、まとめると・単純に同じ設定で圧縮を繰り返すだけでは際限なく劣化することはない。・ただしサンプリングを落とした場合は少々劣化が続く。・設定を変えても際限なく劣化はしてくれない。・位置の移動を伴うと際限なく劣化した。JPEGの劣化は奥が深い。URL欄を実験的に消してる間に廃止されてしまいました。情報を記憶:コメント:<ご注意>書き込まれた内容は公開され、ブログの持ち主だけが削除できます。ReservedJPEG圧縮を繰り返しても際限なく劣化するわけではないコメント(0)。