ImageJ の場合、元データの値に変更を加えず、表示だけに影響を与える、Look Up Table (LUT) というデータが imagePlus に含まれています。この LUT のデータ構造についてのメモです。
この LUT は例えば ImageJ で、RGB データのチャンネル分割を行うと、R, G, B の画像に分割されますが、それぞれ赤、緑、青に表示されます。この表示色を規定しているのが LUT データです。
この LUT データは基本的に Java byte配列 8bit 256 諧調のインデックスカラーデータのようで、256諧調の R, G, B の 3チャンネルのデータで構成されています。ImageJ は、8bit 画像の場合、基本的に、0 -255 の 256 諧調ですが、LUT データを作成するときは class LUT に対し、Java の Byte 配列 x 3チャンネルでデータを与えます。
この場合、
from jarray import zeros
でライブラリーを読み込んでおき、
R = zeros(256, 'b')
G = zeros(256, 'b')
B = zeros(256, 'b')
で初期化しておく必要があります。
Java の Byte 配列の場合、インデックスは ImageJ 標準の 0 -255 ではなく、-128 ~ 127 の正負記号付き (Signed) の値を取ります。
ですが正負記号無し (Unsigned) を LUT に Byte 変数として読み込ませるとき、次のような変換が必要になります。
正負記号なしの 0 - 128 は 正負記号付きの byte 変数では 0 - 128 に、正負記号なしの 129 - 255 は、正負記号付きの byte 変数の -128 - -1 に変換する必要があります。この場合ブラックポイント値は 0、ホワイトポイント値は -1 ということに、中間グレーポイントは 128 (or -127) となります。つまりシャドウ領域は正の値に、ハイライト領域は負の値になります。
このことはどこにも説明が書かれていないので (暗黙の常識?)、探るまでに非常に時間がかかりました。要注意です。

(x 軸を LUT の input y 軸を output とする)
もし、R チャンネルを赤く表示する場合は、R の -128 ~ 127のインデックスに対し、R チャンネルは -128 ~ 127 とインデックス番号と同じ値を入れるのに対し、G, B チャンネルは、どのインデックスに対しても 0 の値が入ることになります。つまり、G, B チャンネルは真っ暗なのに対し、R チャンネルのみ様々な値が入りますので、赤く表示されることになります。
これが、グレースケールで表示する場合は、R, G, B 三チャンネルに対し、等しく -128 ~ 127 とインデックス番号と同じ値が入ることになります。また反転した表示を行う場合は 0 〜 128, -127 ~ -1 のインデックスに対し、逆転した値 -1 〜 -128 および、128 - 0 を与えます。
なお、ImageJ において、スタック構造のデータで RGB カラーを表示させる場合 (=コンポジット RGB。16bit 以上の RGB データは必然的にコンポジット RGB になる) は、R, G, B の各チャンネルデータを入れた ImagePlus に対し、R 表示、G 表示、B 表示の Lut を掛けてマージすることで、RGB 表示を実現しています。各チャンネルデータに対し、わざわざグレースケールの LUT を掛けると、RGB 表示ができずグレースケール表示になってしまいます。この場合 3 チャンネルのデータを持った LUT が 各 3チャンネルにかかっている (合計 3 x 3 で LUT のデータとしては 9 チャンネル分ある) ことになります。
なお、ImageJ のメニューからLUTを掛けると、単チャンネルの画像の場合は問題ありませんが、コンポジット RGB 画像の場合は、R チャンネルにのみ LUT が掛かります。

従って、この場合は常に R チャンネル (スタックの最初のスライスのチャンネル) のデータに基づいて LUT が掛かっている状態となります。この点は要注意です。本来、LUT はカラー画像に対して掛けることが想定されていないと考えるべきかと思います。
ちなみに手持ちの Ver. 1.54f において、この LUT を掛けた RGB ファイルをチャンネル分解して再度チャンネル合成を行うと、LUT の色が変化してしまいますが、おそらくチャンネル合成コマンドの LUT の扱いにバグが含まれているようです。やはりカラーファイルで LUT を使うことをあまり想定していないのでチェックが甘いものと思われます。
さらに、一旦 LUT を掛けたコンポジット RGB 画像を TIFF ファイルに保存し、Bio-format importer で読み込むと、LUT データはリセットされます。Bio-format importer は常に既存の LUT データを剥ぎ取り、新たに各チャンネルごとに、R, G, B の LUT を掛ける仕様となっているようです。
また、RGB データをチャンネル分解した TIFF ファイルを GIMP などの他のアプリケーションに読ませる場合、16bit 以上なら LUT データが読み取られずに、単なるグレースケール画像として読み込まれますが、8 bit の場合はなぜか LUT データが反映されて、赤、緑、青の画像として読み込まれてしまう場合がありますので、他アプリで読ませようと思っている場合は要注意です。imp.getProcessor().setLut(None) で LUT を外してから、TIFF に書き込んだほうが無難です。
--------
LUT からのデータ取得
次に class LUT からデータを取得する方法について説明します。
1つは整数として取得する方法、もう一つは Java の Byte型配列で取得する方法です。
整数として取得する場合は、getRed, getGreen, getBlue メソッドを使います。
仮に LUT のオブジェクト名が Lut とすると、
R = []
for i in range(256):
R.append(Lut.getRed(i))
こうすると、リスト変数、Reds に 0 - 255 の形で各 LUT の値が取得できます。
一方、Java の Byte 配列として取得する場合は、getReds, getGreens, getBlues メソッドを使い、予め Java の Byte 配列を作って置いて
R = zeros(256, 'b')
Lut.getReds(R)
と取得します。この場合は値は 0 - 127, -128 - -1 の形で LUT の値が取得できます。
getReds などは、戻り値がなく、引数として読み込んだ配列に値を直接読み込みます。
------------