FAL 制作メモ

作ったものを見せびらかしたり解説したりします。自作ゲームやクリエイティブコーディングの話が中心です。作ったものの置き場所はこちら→ https://www.fal-works.com/ Twitter→ https://twitter.com/falworks_ja

プログラムで綺麗な配色を作る方法(CIELAB色空間の巻)

これはProcessing Advent Calendar 2017 - Qiitaの20日目の記事です。

一言でいうと、RGBやHSB以外にも色の指定方法があるよというお話です。
いわゆる配色理論の話にはまだ辿り着いていません。

[追記]
CIELABを具体的にどうやって実装するの? という話をまったく書けておりません……。
一応末尾に参考リンクを貼っているので見ていただきたいのですが、自分で変換処理を書くのはたぶんちょっと面倒。
私の(合ってるか分かんないのですが)オレオレ実装がこちら、あと探せば他にもライブラリや実装例があるはず。
知りたいのはそこなんだよ~という方、申し訳ありません!

Colored Particles スクリーンショット
Colored Particles


この記事の趣旨

このたび次のようなスケッチを作りました。
マウスボタン(またはタッチ)でちょっとだけ動きが変化します。

色の指定を楽にやろうとした結果、このスケッチではCIELAB色空間というものを使いました。
調べる過程は楽するどころか大変だったし、力尽きてメインのプログラムはてきとうになってしまったのですが、せっかくなので調べたことを記録しておきたいと思います。

なお毎度のことですが私はネットで少しググっただけの素人です。
色彩工学という分野の話なのですが、色彩の話は(少なくとも素人の私からすると)とても込み入っていて、間違ったことを書いてしまう可能性がかなり高いです。何かおかしい点があればご指摘いただけると幸いです。

目的:色をシステマチックに扱いたい

何か色のあるものを作ろうとすると、問題になるのが配色です。

せっかくプログラミングという手段があるので、手作業で色を調整するよりも、プログラムでランダムに生成したい。
しかし完全にランダムだとみっともない配色になる。
何かしらの機械的な規則や手順で、統一感のある配色を生成したい。

その第一歩として、まずは個々の色をシステマチックに生成・操作できる仕組みが必要だ。

基礎知識:色空間とは

次に述べるRGBが代表例ですが、色を数字で指定しようとすると、3種類の数字が必要になります。
変数が3種類ということは、3次元の空間にプロットできることを意味します。
これが色空間と呼ばれるものです。
色空間 - Wikipedia

よく知られているRGB以外にも、様々な色空間(つまり、どんな変数を用意すれば色を表せるか)が考え出されています。

基本の色空間「RGB」

コンピュータで色を指定するための最も基本的な方式がRGBです。

Red, Green, Blue の三色を混ぜ合わせる割合を変えることで様々な色が作れます。
コンピュータのディスプレイは、まさにこうやって三色の組み合わせで光を出す仕組みになっています。

RGB加法混色
RGB加法混色

RGB色空間の欠点

これの欠点は、どの色をどのくらい混ぜると結果どんな色になるのか、経験がないと想像できないところ。

もちろんこれは、既存のパレットから色を選んだり、結果を見ながら手で微調整したりする分には、たいした欠点にはならないかもしれません。
しかし、もっと直観的なパラメータを指定するだけで色を作れたほうが便利です。

なにより、色のランダム生成に向いていない。
こちらの記事でも書かれていますが、適当に混ぜると「素人っぽい配色」になってしまいます。
cocopon.me

直観的に色を指定できる色空間「HSB(またはHSV)」

上記のRGBの問題をある程度解決してくれるのが、HSB(Hue, Saturation, Brightness)というカラーモデルです。
なお HSV(Hue, Saturation, Value)とも呼ばれますが同じものです。HSVの方が優勢かも。

HSB色空間の利点

直観的に分かりやすい

色相・彩度・明度 という、人間から見ても分かりやすい三要素を使って色が作れます。
色相は赤っぽいとか青っぽいとかの違いで、彩度は鮮やかさのことですね。
「もっと鮮やかに」「もっと暗く」みたいな操作をダイレクトに行えます。

RGBよりも統一感のある配色を作りやすい

例えば彩度・明度を一定にしたまま色相だけをランダムにすると、ある程度統一感を保ったままカラフルな状態が作れます。
Processingでも標準で使えるようになっていて、プログラムで絵を描くときには重宝します。

HSB 彩度70% 明度100%
HSB 彩度70% 明度100%

人間とコンピュータの橋渡し的な位置にいる

HSBは、表面的には違っても内部的にはRGBの亜種みたいなもので、RGBとの変換が容易です。
人間から見て分かりやすく、かつコンピュータでも計算しやすい。
このため、コンピュータで色のデザインをするのに広く使われる方式となっています。

HSB色空間の欠点

多くの場合「HSBは便利!」で話が終わるのですが、問題はここからです。
しばらく使っていると、実はいろいろ不満も出てくるのです。

同じ明度でも色相によって実際の明るさが違う

淡い配色をしようとすると、この欠点が顕著に出ます。
黄色や緑が他の色よりも明るすぎて、白背景に溶け込んでしまうのです。

色相・彩度・明度の三要素に分けたからには、それぞれが独立しているのが本来の姿です。
色相を変えただけで明るさまで変わってしまうのは困る。

勝手にコントラストが生まれるので都合がいいという場合も無くはないのですが、本当ならそれも意識的にやりたいところです。

均等色空間ではないので色の変化にばらつきがある

均等色空間というのはおおざっぱに言うと、パラメータの数値を10から20に変えたときと、70から80に変えたときとで、結果の色が(人間から見て)同じくらい変化する、ということです。

特に、HSBの色相が均等でないという点について、こちらの記事が分かりやすいです。
普段HSBを使っていても、なんか緑の領域が妙に広いなぁ、と感じることは確かに多いです。
Photoshopで理論的に配色はできないものか検証してみた │ Design Spice

色相を360°の円として並べたものを色相環と言います。
HSBの色相環は、RGBの三原色が単純に0°・120°・240°の位置にくるように作ったものなので、人間から見て均等かどうかは考慮されていません。

「配色理論」でググるとわかりますが、多くの理論は色相環上の角度の違いを問題にしています。
色相が均等でないと、そもそもこれらの配色理論を適用できるのかどうかも疑問が出てきます。

人間から見た均等性を重視する色空間「CIELAB」

上記の欠点を克服することを意図された色空間はいくつかあります。
そのうちの一つがCIELABです。
Lab色空間 - Wikipedia

CIEというのは国際照明委員会という団体です。光のプロですね。
ちなみにCIELABはPhotoshopでも採用されているようです。

CIELABの変数L*, a*, b*

下記の3つの変数で色を指定します。
a*とb*を両方0にすると無彩色になります。

  • L* … Lightness、明るさ。最小値の0で黒、最大値の100で白になる
  • a* … 赤⇔緑 のパラメータ
  • b* … 黄⇔青 のパラメータ

a*とb*の代わりに、次のように極座標で表すこともできます(CIELChと呼んだりする)。

  • L* … 明るさ(上と同じ)
  • C* … Chroma(彩度)の略。a* b* 平面上の中心からの距離
  • h* … Hue(色相)の略。a* b* 平面上の中心から見た角度

なぜアスタリスクがついているのかというと、詳細は割愛するが歴史的な理由があるのだ。
エルスター、エースター、ビースターと読むらしい。

RGB/HSBからのマッピング

実はRGBでは現実に存在するすべての色を表せない。
HSBも、RGBを変形しただけの空間なので同様である。

一方CIELABは、ヒトが認識できる色のほぼすべてを含みます。
むしろ空間が広いので、ヒトには認識できない色の方が多かったりする。

RGB色空間の(つまり、ディスプレイで表示可能な)すべての色をCIELAB色空間にマッピングすると、次の画像のように、ちょっと歪な形になります。
(横軸がa*、縦軸がb*。特定のL*の値で区切った断面図です)

CIELAB色空間上のRGBの色域 (L*=80)
CIELAB色空間上のRGBの色域 (L*=80)
CIELAB色空間上のRGBの色域 (L*=50)
CIELAB色空間上のRGBの色域 (L*=50)

これだけ見ると、この範囲から色を選ぶなんて逆に不便では? という感じもしますね。
少し妥協して、範囲外の色はRGB色空間内の似たような色で間に合わせるようにしてしまえば、あとは前述のCIELChをHSBと似たような感覚で使えるようになります。

CIELAB (CIELCh) とHSBの比較

比べてみましょう。
色相以外のパラメータはなんとなく目分量で、CIELABとHSBで似たようなテイストになるようにしました。*1

こちらがHSBの色相環。

HSB色相環 (S=90%, B=85%)
HSB色相環 (S=90%, B=85%)

こちらがCIELAB (CIELCh) の色相環です。

CIELCh色相環 (C*=100, L*=80)
CIELCh色相環 (C*=100, L*=80)

色相以外は固定しているので、できるだけ見た目の明度や彩度のコントラストが無いほうが良いわけです。
この点、CIELABの方がコントラストが控えめになっているのが分かるでしょうか。

色の均等性についてはこの例だとちょっと分かりませんね……。
上のCIELABの図では水色がいくつも続いてしまっていますが、これは青系が他の色よりもRGB領域から離れてしまう度合が高いせいだと思われます(前項のRGB色域の図でも、RGBの青系の領域が狭いのが分かります)。

RGB範囲外の色をクリッピングせざるを得なかったため、少しCIELABの利点を損なっている部分はあるのですが、理論的には改善されているはずです。

まとめ

以上、RGB色空間やHSB色空間にはいくつか欠点があって、CIELAB色空間である程度改善されるというお話でした。

とりあえず、黄色と緑が明るすぎ問題については解消できました。
しかし、いわゆる配色理論にはまだ一歩も踏み込んでおらず、ようやく入り口に立ったという感じです。

あと、RGBとCIELABとの相互変換を自分で実装してみたのですが、芋づる式にXYZ色空間とか、sRGB色空間とかガンマ補正とか、ここには書かなかった知識についてもいろいろ調べ回るはめになってしまいました。
他にも、人間の色の認知において色は平等ではないとか、マンセル・PCCS・NCSなどのカラーシステム、などなど。
こんな広くて深い世界だとは知らなかった……。

タイトルに「巻」とか付けちゃいましたが次巻の予定はまだないです。

参考情報

概観

Color Space
もろもろの色空間やカラーモデルの概要について、私が見つけた範囲で最も簡潔にまとまっていると感じた記事です。
(英語。下の方にメリデメ比較表がある)

HSBとCIELAB

HSL and HSV - Wikipedia
HSBの欠点について詳しく書かれています。(英語)

CIELAB color space - Wikipedia
Labの説明。(英語)
Wikipediaだけでもたくさんの情報があり、キーワードの関係を把握するのにだいぶ時間がかかります。

Lab 表色系 / Lab color space
CIELAB色空間に関する日本語の解説です。

XYZとsRGB

XYZ色空間に迫る(1) - Qiita
この記事では話さなかった、XYZ色空間に関する日本語の詳しい解説です。
CIELAB色空間はこのXYZ色空間から派生したものです。
CIELABで指定した色をディスプレイに表示するためには結局RGBに変換する必要がありますが、その際、XYZ色空間を経由しなければなりません。
なおXYZ色空間は、CIELABに限らず他の様々な色空間を変換するときにも中継地点としてよく使われます。

物理ベースレンダリング -リニアワークフロー編 (1)- | Cygames Engineers' Blog
RGBと一言で言っても、実は線形RGBとsRGBを区別しなければならず、sRGBにするためにガンマ補正というものが必要になるというお話です。
分かりやすいです。

「sRGBのガンマは2.2」ってのは本当?: イメージスキャナ開発室
ガンマ補正に関する、さらに詳しい情報です。
上記の記事と合わせて。

http://www.color.org/chardata/rgb/sRGB.pdf
XYZ色空間から線形RGB空間を経由してsRGB色空間に変換するための式や数値の公式情報です。
Wikipediaに書いてある情報はどうも最新ではないらしく、この2015年4月の改定が今のところ最新かと思われます。

おまけ

過去に、RGB色空間→CIELAB色空間のマッピングを3Dでやったときのやつです。
ちょっと変換が不正確な可能性あり。
こちらで動きます。→ CIELAB color space - OpenProcessing

CIELAB Color Space
CIELAB Color Space


以上です。

*1:CIELABの光源はD50が一般的なようなのですが、ここでは変換が面倒だったのでD65光源にしています。