Javaでサーモグラフィーの色のグラデーションを再現(1-6)

2010年9月29日 (水)

Javaでサーモグラフィーの色のグラデーションを再現(6)

前回 からの続きです

 Javaで「サーモグラフィーの色のグラデーションを再現」のまとめとして作成したソースコードを載せます。

「HeatmapUtility.java」をダウンロード

このクラスは3つのコンストラクタを持っています。

public HeatmapUtility(int max)
public HeatmapUtility(int max, boolean reverse)
public HeatmapUtility(int min, int max, boolean reverse)

 maxは最大値を、minは最小値、reverseはスケールの反転を指定します。
最大値のみを指定する場合には、最小値は0、スケール反転無しになります

HeatmapUtility util = new HeatmapUtility(128);

 最大値128、最小値-128、反転無しとしてインスタンスを作成する場合以下のようになります。

HeatmapUtility util = new HeatmapUtility(-128, 128, false);

 インスタンス化した後、色を取得するにはint getColor()メソッドを使います。

public int getColor(int value)

 コンストラクタで指定した最大値と最小値の範囲で値をvalueに指定すると、サーモグラフィーの色域で対応したint型の色を取得できます。引数に最大値、最小値を超える値を指定した場合は、それぞれ最大値、最小値として扱われます。

 取得したint型の色は、他クラスで色の指定に使ってください。

int colorValue = util.getColor(64);

 java.awt.Colorのコンストラクタへ渡しColorのインスタンスを作成できます。

Color color = new Color(colorValue);

 ソースの中に記述がありますが、今回は単純なマッピングを行っており他にcosを用いたものと、三次関数によって近似したものとが注釈してあります。参考程度に見てみてください。

 温度分布を表すグラデーションには、様々な色の表現方法があるようです。今回紹介した色の移り変わりは一般的なもので、RGB値の移り変わりから見ても妥当だと思われます。しかしながら、紫と橙を用いたヒートマップの表現系や、水色を省いた色域を用いたものなど、企業・製品・研究領域によって変わってくると思われます。

 今後はそういったサーモグラフィーの表現方法の違いを調べ、それらを実装する方法についてまとめようと考えています。

2009年4月 7日 (火)

Javaでサーモグラフィーの色のグラデーションを再現(5)

 前回からの続きでたぶん今回で最後です。

 今まで考えてきた色調の再現方法やJavaの知識を使い、どうやってクラスを作るかを考えます。これはあくまで自分なりの方法なので、違う形でクラスを作ることも全然構わないと思います。みなさんなりに書いてみてください。
 まずクラスの初期設定として

 ・全部で何段階の階調か
 ・スケールの反転

 などがあればよいかと思います。
 サーモグラフィーの色調を全何段階で表現するか、というわけでここでは128や1024など、つまり最大値を設定します。0=黒、最大値=白というわけです。
 スケールの反転というのは、0=赤、最大値=黒、という風に設定することで、色の設定を反転するわけです。この設定はあとからメソッドで変更できるようにして、コンストラクタでも省略できるようにしておけばいいでしょう。あくまでオプションです。

 メソッドとしては引数に0から最大値までのintの値を取り、戻り値としてsRGB値を持つintを返すものが考えられます。Colorクラスのオブジェクトを返してもいいでしょう。
 そしてその中身ですが、指定された値が最大値の何%かを考えて、色と色の間6通りの段階のどの部分に当たるかを出します。さらに、その色域における256段階で何段階目かを計算します。ここまでの計算は共通なので短い記述で済みますが、色域によって色を作るのに6通り処理を記述する必要があります。
 ここについてはもっといい方法がありそうなんですが、とりあえず簡単なのでこうしました。

RGB値:
白 : 赤100% 緑100% 青100%
 ~赤のGBに0-255を乗せる~
赤 : 赤100% 緑  0% 青  0%
 ~赤のGに255-(0-255)を乗せる~
黄 : 赤100% 緑100% 青  0%
 ~緑のRに0-255を乗せる~
緑 : 赤  0% 緑100% 青  0%
 ~緑のBに255-(0-255)を乗せる~
水 : 赤  0% 緑100% 青100%
 ~青のGに0-255を乗せる~
青 : 赤  0% 緑  0% 青100%
 ~黒のBに0-255を乗せる~
黒 : 赤  0% 緑  0% 青  0%

 なんともお粗末なことになってますが、このようにしました。
 基本の7色は事前に定義しておき、各パターン時に各RGBを適宜上書きする感じで、実際は赤緑青黒しか使いません。ううん、どうにも綺麗にいきません。
 とりあえずこの条件分岐先で色を作り最後に色を返します。
 以上が主となるメソッドです。最初の方に反転設定されているかによって引数値を最大値の半分の値に対して反転するする処理を入れておき、後からでも変更できるようにしておけばよいでしょう。
 そして別途その反転設定をするメソッドを付け加えておけば、当初の目的となるクラスはだいたい完成すると思います。

 長々と書いてきましたが、実際はかなり短く、簡単なことですね。とりあえずここまでとして、また後で作ったクラスなどソースで紹介したいです。寝よう。

2009年4月 5日 (日)

Javaでサーモグラフィーの色のグラデーションを再現(4)

 前回の記事からの続きです。

 前回までは色のグラデーションを再現するに当たり、どのようにRGBを設定するかを見てきました。今回は実際にJavaで色を指定するための方法を見ていきます。

 まずJavaにおいて色は、一般的には java.awt パッケージ内のColorクラスによって表現されます。Colorクラスをインポートしてしまえば、Color.BLACKやColor.REDなどを定数としてすぐに使うことができますし、RGB値を実際に指定してインスタンスを作ることができます。

 しかしColorクラスは一つの色を保持するだけで、内部の色を変更するといったことができません。なので今回のようにグラデーションといった処理をするためにはちょっと扱いにくくなります。
 つまり、どんな色になるのかを計算し終えた後で、実際に色として格納するときに使うのがよいでしょう。

 というわけで今回は、int型の変数1つで1色を保持する仕組みを書いておきます。

 Javaに限った話ではないかもしれませんが、32bitのint型の変数でRGB値と透明度を指定することができます。透明度はALPHA値として、sRGB色空間の中で表現されるそうです。
 まずint型のどのbitがどの数値を表すのか、図を見てください。

Alphargb

 32bitを4分割して、それぞれ8bitずつ割り当てられます。8bitでは256段階(0-255)まで表現できます。


Alphargbbitpos


 割り当てられるbitの位置についてですが、左端←が第32bit、右端→が第1bitです。

 図のようにして見ると簡単そうに見えますが、実際”int型の16bitから9bitを255に指定する”といった作業は結構厄介です。特定のbitを指定するためにはビットシフト論理演算の知識が必要となります。

透明度0、赤255、緑0、青0、に指定する例

int red = 0<<24 | 255<<16 | 0<<8 | 0;

赤の値を128に上書きする例

int red = 0<<24 | 255<<16 | 0<<8 | 0;
red &= 255<<24 | 0<<16 | 255<<8 | 0;
red |= 128<<16;

 intを1色として扱う方法は少し中級者向けかもしれません。上記のことは脇道の知識程度にとどめて、RGB値を各色3つの変数で管理したりなど、もっと簡単に扱うことはできると思います。
 最終的にRGBの変化を変数で扱えるようにすればいいだけなのです。

 次からは具体的にJavaでクラスを作ることを考えていきたいと思います。

2009年4月 3日 (金)

Javaでサーモグラフィーの色のグラデーションを再現(3)

 前回の記事の続きです。

 前回はサーモグラフィー的な色調で使用される7色の色と、それらのRGB値について紹介しました。今回はその7色の色のなめらかな移り変わりを実現するための方法を考えます。

Heatgra
 まず基本として、この色調を128段階とします。この中で任意の値(0~127)を指定し、128を6等分して当てはまる色域の部分を決定します。


右の図で、どの色と色の中間なのかを確定します。

 あらかじめ用意している色は白、赤、黄、緑、水色、青、黒、の7種類です。なのでこれらの色と色の中間を考えると、6つの移り変わりの処理が必要になります。

 さて、ここで肝心の色と色の移り変わりの処理について考えます。色と色の移り変わりというのは、RGB値的にはどれか一つが0%から100%に移ったり100%から0%に変化するということです。

 基本的には、RGB値は各色、0~255までの値で指定されることになります。
 全体128段階を6等分すると一つの色域につき約21段階が割り当てられるので、この21段階を、RGB値の0~255に割り当てればいいだけです。

 
 単純に話はここまでで終わってしまうんですが、ここはちょっと工夫して、色調の段階を可変にしたり、色の移り変わりに変化を与えたりすることをちょっと考えてみたいと思います。

 まず、色調の段階について当初128段階にするとしましたが、これは256段階や1024段階など、自由に決められるようにしましょう。これは簡単に実装できて、6つの変わり目について、一つ当たり何段階あるのかを計算すればどんな大きな段階でも対応できます。2048段階ならば、一つの変わり目には約341段階あることになり、これを0~255にマッピングします。
 255よりも大きい段階になると無駄がでてきてしまいます。全体の色域を使い切れる最高は1536段階ほどになるようです。でもそれより大きな段階数にしても大丈夫ですね。

 次に色調の段階を可変にしたりということですが、今までは値の大きさに比例してRGB値も決まる方法でした。いわばxの値に比例するyという関係です。そこで色の中間色が強調されるように関数を使ってマッピングをします。

X_2

Cos_2

 1つ目の図は単純なxとyの比例するグラフですが、2つ目の図はcos関数によってxとyの関係が微妙にずれています。これにより、中間地点の色が、広範囲に鮮明に見えるようになります。
具体的な計算と使う関数は、実際のソースコードで見ましょう。

 今日はこのくらいで。

2009年4月 1日 (水)

Javaでサーモグラフィーの色のグラデーションを再現(2)

 前回の記事から続きです。

 前はサーモグラフィーで使われるような色のグラデーションをJavaで実現するということで、とりあえず試行錯誤の成果として生成できた画像を紹介しました。
 今回はJavaで実際のプログラミングの前段階として、色の基本的な知識や、いろいろ調べたことをメモしておきます。


再現した色調:
Heatgra

 下から上へ、値が大きくなるほど色が青から赤のように移り変わっているのが分かると思います。
 みなさんおなじみの、サーモグラフィーなどでよく見るような色調ですね。
 
 実際に使う色としては、白、赤、黄、緑、水、青、黒の7色です。場合によっては黒と白が無いような画像もあるようですが、一応幅広く表現できるように全7色で試すことにします。

 それで、この7色を使えばいいということはなんとなく分かりますが、問題は色が移り変わる間の中間色をどのように表現すればいいのか、ということです。

 全7色でなく、中間色も全て加えてしまえばいいと思われるかもしれません。しかし、そうすると中間色とその他の色の中間色も加えていくことになり、きりがありません。さらには、内部的にデータを扱うときに、この7色以外を表すにはRGB値を細かく指定する必要があり、面倒です。


各色のRGB値:
白 : 赤100% 緑100% 青100%
赤 : 赤100% 緑  0% 青  0%
黄 : 赤100% 緑100% 青  0%
緑 : 赤  0% 緑100% 青  0%
水 : 赤  0% 緑100% 青100%
青 : 赤  0% 緑  0% 青100%
黒 : 赤  0% 緑  0% 青  0%

 このサーモグラフィー的な色調は、RGBの値的に見ると綺麗に移り変わっているのが分かると思います。これは内部でデータとして扱うときにも分かりやすく作れるということです。
 あとは、この色と色の間をスムーズに補完するための仕組みを考えればよさそうです。

 というわけで今回はここまでとして、次は色と色の間をなめらかに繋ぐための数学を考えます。

2009年3月30日 (月)

Javaでサーモグラフィーの色のグラデーションを再現(1)

作りたい物:
サーモグラフィーでよく見られる、青や緑、赤などのグラデーションで表示される画像

作るのに必要なもの:
温度などの値を渡すと、スケールに応じて適切な色を返してくれるクラス(メソッド?)


 こんな感じで、よくテレビとかで見るサーモグラフィーみたいな色調をうまく作り出すようなのを作りたいと思いました。単純にあんな感じの画像を作れたら面白いなあと思っただけなんですが、結果的に色々と勉強になりました。
 
 ↓というわけでとりあえず今回の試行錯誤でできた画像
Chiruno13d_2

 画像の描画はまた別のクラスでいろいろと試行錯誤しているんですが、今回は密度によって変化した色を取得できるようにしているところがポイントです。とりあえず紹介まで