JA EN
体系画像圧縮
·★ 会員·12分で読めます

JPEGはなぜ劣化するのか — DCTと量子化を1から

写真が10分の1になるとき、何が捨てられているのか。色空間変換・8×8ブロック・DCT・量子化テーブル・ジグザグ走査を順に追い、「品質90」という数字の正体と、ブロックノイズ/モスキートノイズが生まれる場所まで降りていきます。最後は、画像を扱う人が実際に決めることへ落とします。

対象imageタスクcompression

比喩: 捨てる前に、並べ替える

引っ越しで荷物を半分にするとき、目をつぶって箱を捨てる人はいません。まず「毎日使う/たまに使う/たぶん一生使わない」の順に並べ替え、後ろから捨てます。捨てる量が同じでも、並べ替えてから捨てるほうが痛みは桁違いに小さい。

JPEGはこれと寸分違わぬことをします。画像を「人の目が敏感な成分」から「鈍い成分」の順に並べ替え、後ろから捨てる。並べ替える道具がDCT、捨てる操作が量子化です。

全体像: 工程は5つしかない

  1. 色空間変換 — RGBを、明るさ1本と色2本(YCbCr)に組み替える
  2. クロマサブサンプリング — 色の2本だけ解像度を落とす
  3. 8×8ブロックへの分割とDCT — 各ブロックを「波の強さ」の並びに書き換える
  4. 量子化 — 波の強さを粗い目盛りに丸める
  5. ジグザグ走査とエントロピー符号化 — 丸めた結果を可逆に詰める

このうち非可逆なのは2と4だけです。1・3・5は原理的に元へ戻せます。「JPEGの劣化」と呼ばれる現象は、全部この2箇所から出てきます。

明るさと色を分ける

人間の視覚は、明るさの変化には鋭く、色そのものの変化には鈍い。この非対称性を使うため、JPEGはまずRGBを YY(輝度)、CbC_bCrC_r(青系・赤系の色差)に組み替えます。

Y=0.299R+0.587G+0.114BY = 0.299R + 0.587G + 0.114B
(1)

やっていることを日常の言葉にすると、ある画素の赤・緑・青の値を、それぞれ「その色が人にどれくらい明るく見えるか」で重み付けして足しているだけです。出てきた YY が「この画素はどれくらい明るいか」を表す1つの数になります。

この式が言っているのは要するに、緑がいちばん明るく見え、青がいちばん暗く見えるという人間の感度をそのまま重みにした、ということです。色差は CbBYC_b \propto B - YCrRYC_r \propto R - Y、つまり「明るさを引いた残りの色味」。YCbCrに移すと情報が YY に集中し、Cb,CrC_b, C_r は0付近に寄ります。

クロマサブサンプリング: 色の解像度を半分にする

次にJPEGは CbC_bCrC_r の画素数だけを間引きます。表記は 4:2:0(縦横とも半分=色の画素数が4分の1)、4:2:2(横だけ半分)、4:4:4(間引かない)。

4:2:0 なら1画素あたりのデータ量は YY が1、Cb,CrC_b, C_r が合わせて0.5で計1.5バイト相当。RGBの3バイトに対して半分です。DCTにも量子化にも触れていないのに、もう半分。風景写真ではまず気付けませんが、赤い細線や色付きの文字では色の輪郭が滲みます。

8×8ブロックとDCT

各成分は8×8画素のブロックに切り分けられ、以降は完全にブロック単位で、隣を一切参照せずに処理されます。この独立性が、後でブロックノイズの原因になります。

各ブロックに掛けるのが離散コサイン変換(DCT)です。名前は難しそうですが、やっていることは1つ。

F(u,v)=14C(u)C(v)x=07y=07f(x,y)cos(2x+1)uπ16cos(2y+1)vπ16F(u,v) = \frac{1}{4}C(u)C(v)\sum_{x=0}^{7}\sum_{y=0}^{7} f(x,y)\cos\frac{(2x+1)u\pi}{16}\cos\frac{(2y+1)v\pi}{16}
(2)

つまり、64種類の縞模様を1つ持ってきてブロックに重ね、「このブロックはこの縞にどれくらい似ているか」を測って答えを書き留める、という作業です。uuvv はどの縞を選んだか(横方向・縦方向にそれぞれ何本の縞か)、二重の総和が「どれくらい似ているか」をブロックの64画素ぶん合計する部分にあたります。これを64種類ぶん繰り返せば変換は終わりです。

f(x,y)f(x,y) は元の画素値、F(u,v)F(u,v) が変換後の係数、C(0)=1/2C(0)=1/\sqrt{2} で他は1です。式の見た目に怯む必要はありません。64個の画素値を、64種類の「縞模様」の強さに書き換えているだけです。

その64種類(基底)は、左上が「一様な塗り」、右へ行くほど横縞が細かく、下へ行くほど縦縞が細かくなります。左上の F(0,0)F(0,0)DC係数と呼ばれ、そのブロックの平均的な明るさそのもの。残り63個がAC係数で、細かい変化の量を表します。

ここが肝心です。DCTは情報を1ビットも捨てていません。64個の数を別の64個に書き換えただけで、逆変換すれば完全に元へ戻ります(線形代数の記事でいう直交変換=基底の取り替えです)。ではなぜやるのか。自然画像ではエネルギーが左上のごく少数の係数に集中するからです。滑らかな部分が多い写真では、右下の高周波係数はほぼ0に近い。並べ替えの結果「捨ててよいもの」が右下にまとまる——これがDCTの唯一にして最大の仕事です。

FIG 1品質を下げると右下(高周波)の係数から順に0へ丸められ、やがて8×8の境界が段差として見えてくる。捨てているのは「細かい変化」であって、画素をランダムに壊しているわけではない

並べ替えが済んだので、いよいよ捨てます。操作は拍子抜けするほど単純です。

この先にあるもの

§

ここから先は会員限定です

解説記事371本・教科書26章・学生モード48単元・論文精読6本が、月額¥490ですべて読み放題になります。新しい解説は毎日3本ずつ増えます。いつでも解約でき、解約後も期間の終わりまで読めます。

会員の方はログインすると続きが表示されます

コメント

コメントにはログインが必要です