デジタル画像の基礎
JPEGエンコーダやデコーダは、その入出力データとして画像を取り扱うプログラムです。その実装にあたっては、コンピュータが扱えるよう数値化された画像、つまり「デジタル画像(digital image)」に関する知識が不可欠です。本記事ではJPEGコーデックの理解と、JPEGデコーダ実装に必要となる知識を中心に解説していきます。
画像=波(なみ)
あらゆる画像(image)、普段何気なく目に入ってくる風景・人物、書籍やキャンバスに書かれた文字・絵画は、空間的に広がるアナログデータ(アナログ画像)です。簡単のため、まずはモノクロ写真を思い浮かべてください。モノクロ写真のように色彩をもたず濃淡のみで構成される画像は、グレイスケール(grayscale)画像と呼ばれます。
グレイスケール画像は、画像上のそれぞれの位置(X,Y座標)に対する "明るさ(輝度; luminance)1" 情報から構成されたデータです。アナログ画像上の位置と明るさは連続的に変化するため、画像とは 2次元の波(なみ; wave) であると解釈できます。水面に広がる波で例えると分かりやすいでしょうか。明るさを高さ方向(Z座標)へマッピングして考えてください。
「画像=2次元の波」という解釈は、あらゆる画像コーデックの根幹をなす重要な考え方です。詳細説明は後続記事にゆずりますが、JPEGコーデックで利用する DCT(discrete cosine transform; 離散コサイン変換) はこの考え方に基づいたものです。
RGB三原色とカラー画像
先ほどはグレイスケール画像を考えましたが、日常的にはカラー画像を目にする機会のほうが多いでしょう2。カラー画像上の "色(いろ; color)" を数値として表現することで、カラー画像に対しても前節の説明を適用できます。
ご存知のとおり(ご存知でした?)、あらゆる色は赤(Red)・緑(Green)・青(Blue)の三原色を混ぜ合わせて作り出すことができます。三原色の頭文字をとった「RGB値」のほうが馴染みがあるでしょうか3。空間的な広がりを持つ画像全体で考えると、カラー画像(color image)は三原色それぞれに対応するグレイスケール画像3枚の足し算として表現できます。たとえば赤(Red)に対応する画像は、カラー画像から "赤色成分の強度" のみを取り出し、赤色成分が強い領域を明るく/弱い領域を暗く表現したグレイスケール画像となります。それぞれの画像は色彩をもちませんが、見た目に惑わされないよう注意ください。
三原色に分解したそれぞれのグレイスケール画像は、カラー画像を構成するチャネル(channel)もしくはコンポーネント(component)と呼ばれます。また分解されたグレイスケール画像を面と見立て、プレーン(plane)と呼ぶ場合もあります。
デジタル画像とピクセル
ここまでは、すべてアナログデータとしての画像に関する説明でした。コンピュータではアナログデータを直接扱えないため、アナログ画像からデジタル画像への変換が必要です。画像のA/D変換(アナログ/デジタル変換)では「位置のデジタル化」と「明るさのデジタル化」という2種類の変換を行います。
位置のデジタル化によって、画像を ピクセル(pixel) の集まりとして表現できるようになります4。アナログ画像では連続的な実数値で表される位置情報が、デジタル画像ではピクセル座標という離散的な整数値へと変換されます。このA/D変換は標本化(sampling)と呼ばれ、概念的にはアナログ画像を2次元格子で区切って、格子点位置の明るさデータを拾い集める操作に相当します。同じアナログ画像に対して目の細かい格子を用いれば高精細度なデジタル画像が、目の粗い格子を用いれば低精細度なデジタル画像が得られます。2次元格子の目の粗さ、つまり標本化周波数によって、デジタル画像の解像度(resolution)が決まります。
それぞれのピクセル座標における明るさ情報をデジタル化するため、実数値から近い整数値への丸め処理も必要です5。デジタル化後の整数値の範囲としては、コンピュータ上で扱いやすい 2のべき乗 を選ぶのが一般的です。JPEGコーデックが扱う8ビット整数型(いわゆるバイト型)ならば、明るさは0~255の256階調です。グレイスケール画像の1ピクセルは8ビットの情報、カラー画像の1ピクセルは三原色ぶんで8×3=24ビットの情報として表現されます。1ピクセルあたりの表現ビット幅はビット深度(-しんど; bitdepth)と呼ばれ、単位 bpp(bits per pixel) が用いられます。「24ビットカラー」といった語を聞いたことがあるかもしれません。
具体例として、普及帯のディスプレイサイズで表示されるデジタル画像のデータ量を計算してみましょう。1920×1080ピクセル、1ピクセル・1原色あたり8ビット、RGBカラー画像のデータサイズは 1920×1080×8×3=49766400bit、およそ 50Mbit (6.2Mbyte)です。JPEGコーデックを用いないそのままのデジタル画像は、本来この規模のデータサイズなのです。6
おまけ: 標準テスト画像
本記事で用いたトリ画像は、標準テスト画像として用いられる "Kodak Photo CD PCD0992" から一番カラフルなものを選んでみました。
標準テスト画像のなかで最も有名な画像として、「レナ(Lenna)」と呼ばれるポートレート写真があります。よく知られた逸話かもしれませんが、実はこれ、PLAYBOY紙に掲載されていたヌード写真の一部分です。知的好奇心が旺盛な方(?)のために、Wikipedia記事に全身写真へのリンクがあります。NSFW(職場閲覧注意)。
👈 [#1 創刊号][article1] / [#3 データ圧縮の基礎(前編)][article3] 👉
[article1]: http://qiita.com/yohhoy/items/884205d865d21ca3d8cf
[article3]: http://qiita.com/yohhoy/items/2740f4fa207a44f6bf4b
-
より厳密な議論では、"モノクロ写真" と "モノクロディスプレイ" の明るさは区別が必要です。前者は写真という物質表面の明るさ(物体色)であり、写真それ自体の物理的特性(光の反射率)と写真を見る照明の強さ(照度)に依存します。後者はディスプレイ表面から放射される光の明るさ(光源色)です。本記事連載では画像のディスプレイ表示を前提としており、説明を単純化するためにも両者を区別しません。 ↩
-
コンピュータ上ではカラー画像が当たり前になりましたが、実社会ではグレイスケール画像もさまざまな場面で利用されます。身近なグレイスケール画像の例: 一色刷りの書籍や雑誌、モノクロフィルム写真、医療用のレントゲン/超音波/CTスキャン/MRIスキャン写真など。 ↩
-
人によっては、シアン(Cyan)・イエロー(Yellow)・マゼンタ(Magenta)・キー/黒(Key/blacK)の四原色からなる「CYMK値」のほうが馴染み深いかもしれません。RGBとCYMKでは原色を混ぜて作り出す混色(こんしょく)の原理が根本的に異なっており、前者RGBはディスプレイ表示される光源色のための加法混色(additive mixture)、後者CYMKはインク印刷される物体色のための減法混色(subtractive mixture)を前提としています。本記事連載では画像のディスプレイ表示を前提とするため、RGB三原色を用いた加法混色のみを扱います。 ↩
-
すでに広く普及している単語だと思いますが、ピクセル(pixel)は "絵(picture)を構成する要素(element)" という意味の造語でした。"画素(がそ)" と日本語訳されることもあります。 ↩
-
「明るさのデジタル化」で行われるA/D変換は量子化(quantization)と呼ばれます。JPEG圧縮アルゴリズムにも同名の量子化処理フェーズが存在し、広義には同じ操作を行うのですが、混乱を避けるため本文中では言及を控えました。ここでの量子化はアナログ信号からデジタル信号への変換を、JPEGコーデックの量子化はデジタル信号同士での階調変換を表します。 ↩
-
画像コーデックで圧縮されていない状態のデジタル画像は、"非圧縮(uncompressed)画像" とも呼ばれます。相当に誤解されている気がしますが、高機能デジタルカメラが出力する「RAW画像」は、ここでいう "圧縮されていない状態の画像" とは 異なるデータ形式 です。 デジタルカメラのRAW画像は "CMOS/CCD撮像素子で観測されたデータをそのまま記録" という意味であり、本文中で説明している非圧縮RGBカラー画像とはまったくの別物です。分かりやすい違いは、カラー画像に含まれるRGB各色のデータ個数比でしょう。本文中のカラー画像ではRGB比率1:1:1ですが、デジタルカメラのRAW画像ではRGB比率1:2:1が一般的([Bayer配列][wp.bayer])です。
[wp.bayer]: https://ja.wikipedia.org/wiki/%E3%83%99%E3%82%A4%E3%83%A4%E3%83%BC%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%BC ↩