デジタルな画像のはなし (色と明るさ)

技術研究所の (あ) です。
機械学習による画像や写真の分類とかやってます。

学習用に集めた画像を畳み込みニューラルネットワークなどで学習させるわけですが、その際にはまず、集めた画像の要る部分だけを切り出したりする必要があります。また、「ちょっと違っても同じだよ」というようなことを学習させるために画像にフィルタを掛けたり変形したりノイズを加えたりして“Data Augmentation”を行うことも多いです。

こうした作業には、またこれに限らず写真などの解析や操作のためには計算機上でデジタルな画像がどう表現され扱われているのか、ということをちゃんと理解しておいたほうが便利です。「なんかこうすればよいらしい」くらいの認識でも、まあ、なんとかなるかもしれませんが、ちょっと知識があるだけで応用できる度合いがぜんぜん違ったりします。

というわけで今回はデジタルな画像の基礎的な部分の説明をしたいと思います。

ピクセルとその値

ほんとうに初歩的な部分から入りますが、写真のようなデジタルな画像は座標ごとに区切られた「ピクセル」の集まりとして表現されます。座標は普通の画像であれば縦横すなわち x, y の二次元の直交座標系ですが、全天球 360度画像の場合だと方位角と仰角の球面座標系になっていたりします。

各ピクセルは明るさと (あれば) 色の情報を持っています。色の表し方 (表色系) は何通りかあるのですが、コンピュータのディスプレイで表示する用途であれば光の三原色 Red, Green, Blue の三つの明るさで表されます。明るさは、0 (まっくら) から最高値までの整数で表すのが普通です。RGB各 8bit (0~255) や 16bit (0~65535) が使われていることが多いかと思います。

さらっと書きましたが、ここまででも (ふだんはあまり気にする必要はないけれど) 深い理解のためには気をつけておくべき要素がいくつかあります。

RGB

一つは「三原色」の色。ディスプレイなどで人間の眼に知覚できる色のすべてを表現するのは (いろいろあって) 実は難しいので、ディスプレイ上の「三原色」は人間の眼にとっての「原色」とはちょっと違っています (より正確な説明は端折ります…^^;)。そして、複数のディスプレイで R, G, B のそれぞれを実際にどういう色として表示するかが違っていると、同じ RGB の値を指定しても違った色が表示されることになってしまいます。

それでは困るので、各種の「色空間」と呼ばれる規格 (sRGB とか Adobe RGB とか) があり、そこでは R, G, B それぞれの色がどういう色であるかが規定されています。それぞれの規定によって「人間が知覚できる色のうちどれくらいをカバーできるか」が違ってくるのですが、ここでは「普通のパソコンなどのディスプレイで表示できる色の範囲は意外と狭い」ということくらいを覚えておいてください。

ガンマ値

もう一つの要素が、それぞれの「明るさ」の割り振りをどうするか、です。単純に考えると、0~255 の数値が素直に明るさに比例しそうですが、表示装置の特性的にはそんなに素直にいくことはなく、真っ暗を 0、最高値を 1 として実数であらわしたとき、入力の信号の強さ x と実際に表示されるの明るさ y との関係は y = x^γ で近似されます。この近似の係数をγで表すので、この値のことを「ガンマ」とか「ガンマ値」とか呼びます。ガンマ値に合わせて入力するデータを調整したりすることをガンマ補正と呼びます。

さきほど出てきた「色空間」の規格ではそれぞれ想定されるガンマ値も決まっていて、たとえば sRGB では 2.2 です。sRGB の色空間を使ったデータを、実際のガンマ値が 2.2 になっているディスプレイに表示すれば「思ったとおりの明暗」で画像が表示されることになります。もし、ディスプレイの調整が狂ってガンマ値がずれていると、中間調の部分が明るすぎたり暗すぎたりする表示になってしまいます。

入力側の話: ホワイトバランス

さて、ここまでは主に出力 (表示) する側に関わる話でしたが、写真など (というか主に写真の場合)、画像を入力する側にはまた違った要素も入ってきます。

出力側と同様、入力側も (ざっくり言って) R, G, B それぞれの原色ごとの光の強さをセンサでピクセルごとに測ってそれをデジタルデータとします (ベイヤー配列とかそのへんの話はここでは置いておきます)。それで話が終わりならよいのですが、人間の眼というか脳の厄介な、いや、素晴らしい特性として、「環境の光源の光の色合いを補正して色を認識する」というものがあります。

黄色っぽい電球の光の下で白いカップや紙を見て、「白い」と認識しますよね。でも、センサの生の計測値をそのままディスプレイに表示すると、それはかなり黄色っぽいものになります。人間の脳は「全体的に黄色っぽい→黄色っぽい光が当たっている」と理解し、それを補正して、黄色っぽい映像の黄色っぽさを差し引いて色を「認識」します。

写真を撮るときもこれと同じような補正を掛けて記録したほうが人間にとって便利なことが多いので、がんばってこれを補正します。これを「ホワイトバランスの調整」と呼びます。白い (というか無彩色 (グレーなど) の) ところがどういう色味になっているかを見て、そこを無彩色 (R, G, B のそれぞれの明るさが同じくらい) になるよう、調整するわけです。

入力側の明るさ範囲の調整

明るさの認識に関しても人間の眼には独特な特性があり、すなわち対数関数的な認識になっています。明るいところでも、暗いところでも、色の濃淡や明暗が同じように認識できるのはそのおかげです。一方、だいたいのセンサの入出力は線形関数的なので、写真の記録ではそこも補正してやらねば不便です。

また、景色によっては光の当たる明るい部分と影になった暗い部分が混ざっていますが、人間の脳は、たとえその両方の部分を一気に知覚しきれなかったとしても、それぞれに合わせて知覚したイメージを合成します。写真の場合も、明るさのカーブをガンマ補正よりも強引に(?)補正して、明るい部分と暗い部分の両方が見やすいように記録する、ハイダイナミックレンジ(HDR) 補正と呼ばれるような技術があったりします。

とりあえず

色や明るさの表現の話くらいしか書いていなくて augmentation とかに関わるところまで届いてませんが、とりあえず今回はここまでにしておきます。画像データって、構成としては比較的シンプルだと思いますし、あまり普段細かいことを気にする必要はないことも多いのですが、けっこう複雑で面倒な要素が絡むものですよね。機会があればまた続きを書きたいと思います。

  • このエントリーをはてなブックマークに追加