JPEG画像形式の概要(圧縮アルゴリズム)。

JPEG画像の圧縮アルゴリズムについて解説します。

JPEG画像の概要(圧縮アルゴリズム)・目次。

JPEG画像とは。

JPEGとは規格策定団体(ジョイント・フォトグラフィック・エクスパーツ・グループ)の名称であり、正しくはJFIF画像(JPEG・ファイル・インターチェンジ・フォーマット)と言うべきですが、現状数あるJPEG策定規格でほぼ唯一JFIF画像のみが採用されており、JPEG画像と呼んでも殆ど差障りが無いようです。

JPEG形式は、策定団体の名前どおり、写真の効率良い圧縮を行うためのフォーマットです。

尚、以下のJPEG画像に関する説明は最もよく使われているベースライン方式を想定して解説したものですが、他の方式(特にプログレッシヴJPEG形式)も圧縮の際のデータの扱いが異なるだけで、大きな違いがある訳ではありません。

JPEG圧縮の手順。

JPEG画像の圧縮アルゴリズムは、GIF画像PNG画像に較べて遙かに複雑です。

具体的には、JPEG画像の圧縮アルゴリズムは、以下のようになります。

  1. ピクセルのデータをRGB形式からYCrCb形式に変換する
  2. YCrCb形式のデータをサンプリングする
  3. 分割されたブロック毎に処理をする

以下、それぞれの処理について解説していきましょう。

1. ピクセルのデータをRGB形式からYCrCb形式に変換する。

RGB形式はピクセルのデータを赤・緑・青の光三原色の値に変換する方式ですが、JPEG圧縮ではこれをYCrCb方式、すなわち輝度・赤方向の色相・青方向の色相の三要素に変換します。

この方が処理がし易いからです。

具体的な変換公式はこうなります。

RGB方式からYCrCb方式への変換公式。
  • Y = 0.299R + 0.587G + 0.114B - 128
  • Cb = - 0.1687R - 0.3313G + 0.5B + 128
  • Cr = 0.5R - 0.4187G - 0.0813B + 128
  • JPEG形式の仕様書では、Y成分に関して128を差引いていませんが、実際のJPEG圧縮処理では差引かなければなりません。
YCrCb方式からRGB方式への変換公式。
  • R = (Y + 128) + 1.402(Cr-128)
  • G = (Y + 128) - 0.34414(Cb-128) - 0.71414(Cr-128)
  • B = (Y + 128) + 1.772(Cb-128)
  • JPEG形式の仕様書では、Y成分に関して128を加えていませんが、実際のJPEG圧縮処理では加えなければなりません。

2. YCrCb形式のデータをサンプリングする。

JPEG画像では輝度情報、色相情報(赤方向及び青方向)とも8ピクセルズ四方のブロック単位で圧縮/展開されます。

一般に人間の目は細かな輝度の違いには敏感ですが、色相の細かな違いは見落とし易いという性質があります。

このため、多くのJPEG画像では、圧縮データの削減のために色相情報は1ピクセルおきに間引きして取得しております。

つまり、多くの場合、色相情報のブロックは輝度情報のブロックより少なく取得されます。

このため、対応する画像上の領域に合わせて、輝度情報ブロック4に対して色相情報ブロックは赤方向青方向とも1ずつを対応させ(4:1:1でサンプリングして)、これを処理の一単位(MCU)とします。

具体的には縦横4ブロック(16ピクセルズ四方)の輝度情報に対して、色相情報は縦横とも1ピクセルおきにデータを取得して1ブロックに見立てます。

具体的には4:1:1でのサンプリングでは、一単位(MCU)について、左上の輝度情報ブロック, 右上の輝度情報ブロック, 左下の輝度情報ブロック, 右下の輝度情報ブロック, 赤方向の色相情報ブロック(縦横とも1ピクセルおきに間引きしたデータ)及び青方向の色相情報ブロック(縦横とも1ピクセルおきに間引きしたデータ)の順に六個のブロックに分割されます。

3. 分割されたブロック毎に処理をする。

JPEG方式のアルゴリズムでは、形式に従ってMCUに分割されますが、実際の処理は8ピクセルズ四方に分けられたブロック単位です。

例えば4:1:1サンプリング形式なら、1MCUに対して六つのブロックが生じますが、それぞれが個別に処理される事になります。

3.1. DCT変換を行う。

DCT変換とは離散フーリエ変換の一種で、8ピクセルズ四方(64個)のデータを周波数分解するものです。

こうする事で、一見無秩序なピクセルの並びも、整然としたデータの並びに変換されるのです。

JPEG画像の圧縮で用いられている具体的なDCT変換の公式は、以下の通りです。

変換前のピクセル値をs(x,y)、変換後の値をS(u,v)としたとき、

一方、JPEG画像の展開で用いられているIDCT変換(逆DCT変換)の公式は、以下の通りです。

逆変換前のピクセル値をS(x,y)、逆変換後の値をs(u,v)としたとき、

DCT変換によって、64ピクセルズの値は64段階の周波数成分に分解されますが、このとき、周波数が高ければ高いほど細かなピクセルの変化を表すものと理解すればよいでしょう。

ただ、高周波成分は実際には一般人には目に付かないほどの細かい情報であり、このため、次の量子化で大抵削られてしまいます。

3.2. データを量子化する。

量子化とは専門的な用語ですが、要するに細かい誤差を切捨てる事です。

具体的なやり方は実に単純で、整数割算、すなわち整数で割って端数を切落す事で実現します。

実際には64ピクセルズ毎に割る数を定義しており、その情報を量子化テーブルとして与えておきます。

3.3. DCT変換したデータを一列に整列させる。

DCT変換されたデータも8ピクセルズ四方のデータとなります。

そこで、左上隅のデータを直流成分(DC成分)、残りの63個のデータを交流成分(AC成分)として取扱います。

直流成分は前のブロックの直流成分との差を情報として取扱い、直流成分に続いて交流成分をジグザグスキャンと呼ばれる規則に従って一列に並べ直します。

ジグザグスキャンとは、64個のデータが縦横8つに並べられているものを、ジグザグ状にスキャンしていくと言うものです。

具体的には以下のようになります。

  1. 左上の0番成分(実際には0番成分は直流成分なのでスキャンはされません)を起点とします。
  2. そこから右隣へ進み、左下方向にスキャンします。
  3. 以下、右下の63番成分にたどり着くまで繰り返します。

      • 左端に着いたら一段下がって右上方向にスキャンします。
      • 最下段に着いたら右隣に進んで右上方向にスキャンします。
      • 右端に着いたら一段下がって、左下方向にスキャンします。
      • 最上段に着いたら右隣に進んで左下方向にスキャンします。

3.4. 一列に整列させたデータをエントロピー符号化(圧縮)する。

JPEG方式のアルゴリズムでのエントロピー符号化(圧縮)にはハフマン符号が使われます。

ハフマン符号PNG画像形式に採用されているデフレート圧縮でも使われておりますが、頻度の高いデータに短いビット数の符号を割当てる事で全体のビット数を減らすと言う形で圧縮する方法です。

一般にハフマン符号を用いて圧縮する形式では、予めハフマン符号を仕様で定義してそれを使う事で処理を単純化出来るものです。

しかしながら、JPEG方式では固定ハフマン符号が仕様で定義されておらず、従って個別にハフマン符号を定義しなければなりません。

ハフマン符号は直流成分用と交流成分用を用意します。

更に多くのエンコーダは輝度成分と色相成分で異なるハフマン符号表セット(直流成分用と交流成分用の組)を用意している場合が多いですが、同じ符号表セットを使っても構いません。

実際の符号化は、以下のようになります。

直流成分。

直流成分はデータの値のビット数を調べ、データの上の方の無駄なビットを削ります。

そして、そのビット数をハフマン符号で表現してデータの前に付けます。

つまり、「ハフマン符号」「データ」という形になります。

注意(平成16年10月20日)。
ハフマン符号の値の範囲は限られているため、直流成分の差分が一方的に膨れ上がるとオーヴァフロウを来たす事になり、その場合正常に表示出来なくなります。このため、一定数のMCUを処理する毎に直流成分の差分データをクリアする必要があります。詳しくはファイルフォーマット篇DRIセグメント/RSTnセグメントの項をご覧下さい。
交流成分。

交流成分は前に連続しているゼロデータの個数を数え、ゼロで無いデータのビット数に対して直流成分同様ビット数を調べてデータのビット数を減らします。

交流成分のハフマン符号は、前に続いているゼロデータの個数とゼロで無いデータのビット数を組合わせたものとなります。

尚、ゼロデータが16個連続する場合はZRL符号と呼ばれる特別な符号を発行して16個分のゼロデータを表現します。この場合、更にゼロデータが後続していても、新たにゼロから数え直します。

先行するゼロデータが15個以内の場合は「先行するゼロデータ数と後続するデータのビット数を表すハフマン符号」「後続するゼロで無いデータ」と言う形に符号化されます。

また、一番後ろの方でゼロデータが連続する場合、一番最後のゼロでないデータを符号化した後にEOB符号と呼ばれる特別なを発行する事で符号化を打切る事が出来ます。

すなわち、交流成分は63個のデータを漏れなく符号化するか、一番最後の非ゼロデータを符号化した後にEOB符号を発行するかのどちらかとなります。

圧縮されたJPEG画像の展開方法。

JPEG画像の展開アルゴリズムは、圧縮手順の逆を辿ればいい訳ですが、ファイル形式との絡みで以下のようになります。

  1. JFIF形式である事を確認する。
  2. 画像に関する情報(幅・高さなど)を取得する。
  3. 量子化テーブル・ハフマン符号表を取得する。
  4. 画像データが出て来るまで余計なデータを読み飛ばす。
  5. 画像データを以下の要領で輝度情報のブロック、色相情報のブロックの順に展開する。

    1. ハフマン符号を解読する。同時に逆量子化を行う。
    2. 8ピクセルズ四方のデータに整列する。
    3. 逆DCT変換を行ってもとの情報を取得する。
    4. ピクセル列に反映させる。

ページ外へのご案内。